Ignore:
File:
1 edited

Legend:

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

    r90f1f19 rbe0ec50  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2023 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 
     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? */
    132155        if ((params->flags & wndf_popup) != 0)
    133156                ds_seat_set_popup(seat, wnd);
     
    135158                ds_seat_set_focus(seat, wnd);
    136159
     160        /* Is this window a panel? */
     161        if ((params->flags & wndf_avoid) != 0)
     162                ds_display_update_max_rect(wnd->display);
     163
    137164        (void) ds_display_paint(wnd->display, NULL);
    138165
    139         *rgc = wnd;
     166        *rwnd = wnd;
    140167        return EOK;
    141168error:
    142169        if (wnd != NULL) {
     170                ds_client_remove_window(wnd);
     171                ds_display_remove_window(wnd);
     172                if (wnd->mgc != NULL)
     173                        mem_gc_delete(wnd->mgc);
    143174                if (wnd->bitmap != NULL)
    144175                        gfx_bitmap_destroy(wnd->bitmap);
     176                if (wnd->caption != NULL)
     177                        free(wnd->caption);
    145178                free(wnd);
    146179        }
     
    158191
    159192        disp = wnd->display;
     193
     194        ds_window_unfocus(wnd);
    160195
    161196        ds_client_remove_window(wnd);
    162197        ds_display_remove_window(wnd);
    163198
     199        if ((wnd->flags & wndf_avoid) != 0)
     200                ds_display_update_max_rect(disp);
     201
    164202        mem_gc_delete(wnd->mgc);
    165203
     
    167205                gfx_bitmap_destroy(wnd->bitmap);
    168206
     207        free(wnd->caption);
    169208        free(wnd);
    170209
     
    178217void ds_window_bring_to_top(ds_window_t *wnd)
    179218{
    180         ds_display_t *disp = wnd->display;
    181 
    182         ds_display_remove_window(wnd);
    183         ds_display_add_window(disp, wnd);
     219        ds_display_window_to_top(wnd);
    184220        (void) ds_display_paint(wnd->display, NULL);
    185221}
     
    193229{
    194230        return wnd->gc;
     231}
     232
     233/** Determine if window is visible.
     234 *
     235 * @param wnd Window
     236 * @return @c true iff window is visible
     237 */
     238bool ds_window_is_visible(ds_window_t *wnd)
     239{
     240        return (wnd->flags & wndf_minimized) == 0;
    195241}
    196242
     
    207253        gfx_rect_t crect;
    208254
    209         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_paint");
     255        log_msg(LOG_DEFAULT, LVL_DEBUG2, "ds_window_paint");
     256
     257        /* Skip painting the window if not visible */
     258        if (!ds_window_is_visible(wnd))
     259                return EOK;
    210260
    211261        if (rect != NULL) {
     
    352402        bool newr;
    353403
    354         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_repaint_preview");
     404        log_msg(LOG_DEFAULT, LVL_DEBUG2, "ds_window_repaint_preview");
    355405
    356406        /*
     
    396446 * @param wnd Window
    397447 * @param pos Position where mouse button was pressed
    398  */
    399 static void ds_window_start_move(ds_window_t *wnd, gfx_coord2_t *pos)
     448 * @param pos_id Positioning device ID
     449 */
     450static void ds_window_start_move(ds_window_t *wnd, gfx_coord2_t *pos,
     451    sysarg_t pos_id)
    400452{
    401453        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_start_move (%d, %d)",
     
    406458
    407459        wnd->orig_pos = *pos;
     460        wnd->orig_pos_id = pos_id;
    408461        wnd->state = dsw_moving;
    409462        wnd->preview_pos = wnd->dpos;
     
    435488        wnd->dpos = nwpos;
    436489        wnd->state = dsw_idle;
     490        wnd->orig_pos_id = 0;
    437491
    438492        (void) ds_display_paint(wnd->display, NULL);
     
    450504        gfx_rect_t old_rect;
    451505
    452         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_move (%d, %d)",
     506        log_msg(LOG_DEFAULT, LVL_DEBUG2, "ds_window_update_move (%d, %d)",
    453507            (int) pos->x, (int) pos->y);
    454508
     
    469523 * @param rsztype Resize type (which part of window is being dragged)
    470524 * @param pos Position where mouse button was pressed
     525 * @param pos_id Positioning device ID
    471526 */
    472527static void ds_window_start_resize(ds_window_t *wnd,
    473     display_wnd_rsztype_t rsztype, gfx_coord2_t *pos)
     528    display_wnd_rsztype_t rsztype, gfx_coord2_t *pos, sysarg_t pos_id)
    474529{
    475530        ds_seat_t *seat;
     
    482537                return;
    483538
     539        /* Determine which seat started the resize */
     540        seat = ds_display_seat_by_idev(wnd->display, pos_id);
     541        if (seat == NULL)
     542                return;
     543
    484544        wnd->orig_pos = *pos;
     545        wnd->orig_pos_id = pos_id;
    485546        wnd->state = dsw_resizing;
    486547        wnd->rsztype = rsztype;
    487548        wnd->preview_rect = wnd->rect;
    488549
    489         // XXX Need client to tell us which seat started the resize!
    490         seat = ds_display_first_seat(wnd->display);
    491550        ctype = display_cursor_from_wrsz(rsztype);
    492551        ds_seat_set_wm_cursor(seat, wnd->display->cursor[ctype]);
     
    518577        ds_client_post_resize_event(wnd->client, wnd, &nrect);
    519578
    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);
     579        /* Determine which seat started the resize */
     580        seat = ds_display_seat_by_idev(wnd->display, wnd->orig_pos_id);
     581        if (seat != NULL)
     582                ds_seat_set_wm_cursor(seat, NULL);
     583
     584        wnd->orig_pos_id = 0;
    523585
    524586        (void) ds_display_paint(wnd->display, NULL);
     
    536598        gfx_rect_t old_rect;
    537599
    538         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_resize (%d, %d)",
     600        log_msg(LOG_DEFAULT, LVL_DEBUG2, "ds_window_update_resize (%d, %d)",
    539601            (int) pos->x, (int) pos->y);
    540602
     
    575637 * @param wnd Window
    576638 * @param event Position event
     639 *
     640 * @return EOK on success or an error code
    577641 */
    578642errno_t ds_window_post_pos_event(ds_window_t *wnd, pos_event_t *event)
     
    580644        pos_event_t tevent;
    581645        gfx_coord2_t pos;
     646        sysarg_t pos_id;
    582647        gfx_rect_t drect;
    583648        bool inside;
    584649
    585         log_msg(LOG_DEFAULT, LVL_DEBUG,
     650        log_msg(LOG_DEFAULT, LVL_DEBUG2,
    586651            "ds_window_post_pos_event type=%d pos=%d,%d", event->type,
    587652            (int) event->hpos, (int) event->vpos);
     
    589654        pos.x = event->hpos;
    590655        pos.y = event->vpos;
     656        pos_id = event->pos_id;
    591657        gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
    592658        inside = gfx_pix_inside_rect(&pos, &drect);
    593659
    594         if (event->type == POS_PRESS && event->btn_num == 2 && inside) {
    595                 ds_window_start_move(wnd, &pos);
     660        if (event->type == POS_PRESS && event->btn_num == 2 && inside &&
     661            (wnd->flags & wndf_maximized) == 0) {
     662                ds_window_start_move(wnd, &pos, pos_id);
    596663                return EOK;
    597664        }
    598665
    599666        if (event->type == POS_RELEASE) {
    600                 if (wnd->state == dsw_moving) {
     667                /* Finish move/resize if they were started by the same seat */
     668                if (wnd->state == dsw_moving &&
     669                    ds_window_orig_seat(wnd, pos_id)) {
    601670                        ds_window_finish_move(wnd, &pos);
    602671                        return EOK;
    603672                }
    604673
    605                 if (wnd->state == dsw_resizing) {
     674                if (wnd->state == dsw_resizing &&
     675                    ds_window_orig_seat(wnd, pos_id)) {
    606676                        ds_window_finish_resize(wnd, &pos);
    607677                        return EOK;
     
    610680
    611681        if (event->type == POS_UPDATE) {
    612                 if (wnd->state == dsw_moving) {
     682                /* Update move/resize if they were started by the same seat */
     683                if (wnd->state == dsw_moving &&
     684                    ds_window_orig_seat(wnd, pos_id)) {
    613685                        ds_window_update_move(wnd, &pos);
    614686                        return EOK;
    615687                }
    616688
    617                 if (wnd->state == dsw_resizing) {
     689                if (wnd->state == dsw_resizing &&
     690                    ds_window_orig_seat(wnd, pos_id)) {
    618691                        ds_window_update_resize(wnd, &pos);
    619692                        return EOK;
     
    632705 *
    633706 * @param wnd Window
     707 * @return EOK on success or an error code
    634708 */
    635709errno_t ds_window_post_focus_event(ds_window_t *wnd)
    636710{
     711        display_wnd_focus_ev_t efocus;
     712        errno_t rc;
     713        ds_wmclient_t *wmclient;
     714
    637715        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_focus_event");
    638716
    639         return ds_client_post_focus_event(wnd->client, wnd);
     717        /* Increase focus counter */
     718        ++wnd->nfocus;
     719        efocus.nfocus = wnd->nfocus;
     720
     721        rc = ds_client_post_focus_event(wnd->client, wnd, &efocus);
     722        if (rc != EOK)
     723                return rc;
     724
     725        /* Notify window managers about window information change */
     726        wmclient = ds_display_first_wmclient(wnd->display);
     727        while (wmclient != NULL) {
     728                ds_wmclient_post_wnd_changed_event(wmclient, wnd->id);
     729                wmclient = ds_display_next_wmclient(wmclient);
     730        }
     731
     732        return EOK;
    640733}
    641734
     
    643736 *
    644737 * @param wnd Window
     738 * @return EOK on success or an error code
    645739 */
    646740errno_t ds_window_post_unfocus_event(ds_window_t *wnd)
    647741{
     742        display_wnd_unfocus_ev_t eunfocus;
     743        errno_t rc;
     744        ds_wmclient_t *wmclient;
     745
    648746        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_unfocus_event");
    649747
    650         return ds_client_post_unfocus_event(wnd->client, wnd);
     748        /* Decrease focus counter */
     749        --wnd->nfocus;
     750        eunfocus.nfocus = wnd->nfocus;
     751
     752        rc = ds_client_post_unfocus_event(wnd->client, wnd, &eunfocus);
     753        if (rc != EOK)
     754                return rc;
     755
     756        /* Notify window managers about window information change */
     757        wmclient = ds_display_first_wmclient(wnd->display);
     758        while (wmclient != NULL) {
     759                ds_wmclient_post_wnd_changed_event(wmclient, wnd->id);
     760                wmclient = ds_display_next_wmclient(wmclient);
     761        }
     762
     763        return EOK;
    651764}
    652765
     
    656769 * @param pos Position where the pointer was when the move started
    657770 *            relative to the window
     771 * @param pos_id Positioning device ID
    658772 * @param event Button press event
    659773 */
    660 void ds_window_move_req(ds_window_t *wnd, gfx_coord2_t *pos)
     774void ds_window_move_req(ds_window_t *wnd, gfx_coord2_t *pos, sysarg_t pos_id)
    661775{
    662776        gfx_coord2_t orig_pos;
     
    666780
    667781        gfx_coord2_add(&wnd->dpos, pos, &orig_pos);
    668         ds_window_start_move(wnd, &orig_pos);
     782        ds_window_start_move(wnd, &orig_pos, pos_id);
    669783}
    670784
     
    686800{
    687801        *dpos = wnd->dpos;
     802}
     803
     804/** Get maximized window rectangle.
     805 *
     806 * @param wnd Window
     807 */
     808void ds_window_get_max_rect(ds_window_t *wnd, gfx_rect_t *rect)
     809{
     810        *rect = wnd->display->max_rect;
    688811}
    689812
     
    694817 * @param pos Position where the pointer was when the resize started
    695818 *            relative to the window
     819 * @param pos_id Positioning device ID
    696820 * @param event Button press event
    697821 */
    698822void ds_window_resize_req(ds_window_t *wnd, display_wnd_rsztype_t rsztype,
    699     gfx_coord2_t *pos)
     823    gfx_coord2_t *pos, sysarg_t pos_id)
    700824{
    701825        gfx_coord2_t orig_pos;
    702826
    703         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_resize_req (%d, %d, %d)",
    704             (int) rsztype, (int) pos->x, (int) pos->y);
     827        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_resize_req (%d, %d, %d, %d)",
     828            (int)rsztype, (int)pos->x, (int)pos->y, (int)pos_id);
    705829
    706830        gfx_coord2_add(&wnd->dpos, pos, &orig_pos);
    707         ds_window_start_resize(wnd, rsztype, &orig_pos);
     831        ds_window_start_resize(wnd, rsztype, &orig_pos, pos_id);
    708832}
    709833
     
    711835 *
    712836 * @param wnd Window
     837 * @return EOK on success or an error code
    713838 */
    714839errno_t ds_window_resize(ds_window_t *wnd, gfx_coord2_t *offs,
     
    761886        wnd->rect = *nrect;
    762887
     888        if ((wnd->flags & wndf_avoid) != 0)
     889                ds_display_update_max_rect(wnd->display);
     890
    763891        (void) ds_display_paint(wnd->display, NULL);
     892        return EOK;
     893}
     894
     895/** Minimize window.
     896 *
     897 * @param wnd Window
     898 * @return EOK on success or an error code
     899 */
     900errno_t ds_window_minimize(ds_window_t *wnd)
     901{
     902        /* If already minimized, do nothing and return success. */
     903        if ((wnd->flags & wndf_minimized) != 0)
     904                return EOK;
     905
     906        ds_window_unfocus(wnd);
     907
     908        wnd->flags |= wndf_minimized;
     909        (void) ds_display_paint(wnd->display, NULL);
     910        return EOK;
     911}
     912
     913/** Unminimize window.
     914 *
     915 * @param wnd Window
     916 * @return EOK on success or an error code
     917 */
     918errno_t ds_window_unminimize(ds_window_t *wnd)
     919{
     920        /* If not minimized, do nothing and return success. */
     921        if ((wnd->flags & wndf_minimized) == 0)
     922                return EOK;
     923
     924        wnd->flags &= ~wndf_minimized;
     925        (void) ds_display_paint(wnd->display, NULL);
     926        return EOK;
     927}
     928
     929/** Maximize window.
     930 *
     931 * @param wnd Window
     932 * @return EOK on success or an error code
     933 */
     934errno_t ds_window_maximize(ds_window_t *wnd)
     935{
     936        gfx_coord2_t old_dpos;
     937        gfx_rect_t old_rect;
     938        gfx_coord2_t offs;
     939        gfx_rect_t max_rect;
     940        gfx_rect_t nrect;
     941        errno_t rc;
     942
     943        /* If already maximized, do nothing and return success. */
     944        if ((wnd->flags & wndf_maximized) != 0)
     945                return EOK;
     946
     947        /* Remember the old window rectangle and display position */
     948        old_rect = wnd->rect;
     949        old_dpos = wnd->dpos;
     950
     951        ds_window_get_max_rect(wnd, &max_rect);
     952
     953        /* Keep window contents on the same position on the screen */
     954        offs.x = max_rect.p0.x - wnd->dpos.x;
     955        offs.y = max_rect.p0.y - wnd->dpos.y;
     956
     957        /* Maximized window's coordinates will start at 0,0 */
     958        gfx_rect_rtranslate(&max_rect.p0, &max_rect, &nrect);
     959
     960        rc = ds_window_resize(wnd, &offs, &nrect);
     961        if (rc != EOK)
     962                return rc;
     963
     964        /* Set window flags, remember normal rectangle */
     965        wnd->flags |= wndf_maximized;
     966        wnd->normal_rect = old_rect;
     967        wnd->normal_dpos = old_dpos;
     968
     969        return EOK;
     970}
     971
     972/** Unmaximize window.
     973 *
     974 * @param wnd Window
     975 * @return EOK on success or an error code
     976 */
     977errno_t ds_window_unmaximize(ds_window_t *wnd)
     978{
     979        gfx_coord2_t offs;
     980        errno_t rc;
     981
     982        /* If not maximized, do nothing and return success. */
     983        if ((wnd->flags & wndf_maximized) == 0)
     984                return EOK;
     985
     986        /* Keep window contents on the same position on the screen */
     987        offs.x = wnd->normal_dpos.x - wnd->dpos.x;
     988        offs.y = wnd->normal_dpos.y - wnd->dpos.y;
     989
     990        rc = ds_window_resize(wnd, &offs, &wnd->normal_rect);
     991        if (rc != EOK)
     992                return rc;
     993
     994        /* Clear maximized flag */
     995        wnd->flags &= ~wndf_maximized;
     996
    764997        return EOK;
    765998}
     
    8071040 *
    8081041 * @param wnd Window
     1042 * @param cursor New cursor
    8091043 * @return EOK on success, EINVAL if @a cursor is invalid
    8101044 */
     
    8201054}
    8211055
     1056/** Set window caption.
     1057 *
     1058 * @param wnd Window
     1059 * @param caption New caption
     1060 *
     1061 * @return EOK on success, EINVAL if @a cursor is invalid
     1062 */
     1063errno_t ds_window_set_caption(ds_window_t *wnd, const char *caption)
     1064{
     1065        char *dcaption;
     1066        ds_wmclient_t *wmclient;
     1067
     1068        dcaption = str_dup(caption);
     1069        if (dcaption == NULL)
     1070                return ENOMEM;
     1071
     1072        free(wnd->caption);
     1073        wnd->caption = dcaption;
     1074
     1075        /* Notify window managers about window information change */
     1076        wmclient = ds_display_first_wmclient(wnd->display);
     1077        while (wmclient != NULL) {
     1078                ds_wmclient_post_wnd_changed_event(wmclient, wnd->id);
     1079                wmclient = ds_display_next_wmclient(wmclient);
     1080        }
     1081
     1082        return EOK;
     1083}
     1084
     1085/** Find alternate window with the allowed flags.
     1086 *
     1087 * An alternate window is a *different* window that is preferably previous
     1088 * in the display order and only has the @a allowed flags.
     1089 *
     1090 * @param wnd Window
     1091 * @param allowed_flags Bitmask of flags that the window is allowed to have
     1092 *
     1093 * @return Alternate window matching the criteria or @c NULL if there is none
     1094 */
     1095ds_window_t *ds_window_find_prev(ds_window_t *wnd,
     1096    display_wnd_flags_t allowed_flags)
     1097{
     1098        ds_window_t *nwnd;
     1099
     1100        /* Try preceding windows in display order */
     1101        nwnd = ds_display_next_window(wnd);
     1102        while (nwnd != NULL && (nwnd->flags & ~allowed_flags) != 0) {
     1103                nwnd = ds_display_next_window(nwnd);
     1104        }
     1105
     1106        /* Do we already have a matching window? */
     1107        if (nwnd != NULL && (nwnd->flags & ~allowed_flags) == 0) {
     1108                return nwnd;
     1109        }
     1110
     1111        /* Try succeeding windows in display order */
     1112        nwnd = ds_display_first_window(wnd->display);
     1113        while (nwnd != NULL && nwnd != wnd &&
     1114            (nwnd->flags & ~allowed_flags) != 0) {
     1115                nwnd = ds_display_next_window(nwnd);
     1116        }
     1117
     1118        if (nwnd == wnd)
     1119                return NULL;
     1120
     1121        return nwnd;
     1122}
     1123
     1124/** Find alternate window with the allowed flags.
     1125 *
     1126 * An alternate window is a *different* window that is preferably previous
     1127 * in the display order and only has the @a allowed flags.
     1128 *
     1129 * @param wnd Window
     1130 * @param allowed_flags Bitmask of flags that the window is allowed to have
     1131 *
     1132 * @return Alternate window matching the criteria or @c NULL if there is none
     1133 */
     1134ds_window_t *ds_window_find_next(ds_window_t *wnd,
     1135    display_wnd_flags_t allowed_flags)
     1136{
     1137        ds_window_t *nwnd;
     1138
     1139        /* Try preceding windows in display order */
     1140        nwnd = ds_display_prev_window(wnd);
     1141        while (nwnd != NULL && (nwnd->flags & ~allowed_flags) != 0) {
     1142                nwnd = ds_display_prev_window(nwnd);
     1143        }
     1144
     1145        /* Do we already have a matching window? */
     1146        if (nwnd != NULL && (nwnd->flags & ~allowed_flags) == 0) {
     1147                return nwnd;
     1148        }
     1149
     1150        /* Try succeeding windows in display order */
     1151        nwnd = ds_display_last_window(wnd->display);
     1152        while (nwnd != NULL && nwnd != wnd &&
     1153            (nwnd->flags & ~allowed_flags) != 0) {
     1154                nwnd = ds_display_prev_window(nwnd);
     1155        }
     1156
     1157        if (nwnd == wnd)
     1158                return NULL;
     1159
     1160        return nwnd;
     1161}
     1162
     1163/** Remove focus from window.
     1164 *
     1165 * Used to switch focus to another window when closing or minimizing window.
     1166 *
     1167 * @param wnd Window
     1168 */
     1169void ds_window_unfocus(ds_window_t *wnd)
     1170{
     1171        ds_seat_t *seat;
     1172
     1173        /* Make sure window is no longer focused in any seat */
     1174        seat = ds_display_first_seat(wnd->display);
     1175        while (seat != NULL) {
     1176                ds_seat_unfocus_wnd(seat, wnd);
     1177                seat = ds_display_next_seat(seat);
     1178        }
     1179}
     1180
     1181/** Determine if input device belongs to the same seat as the original device.
     1182 *
     1183 * Compare the seat ownning @a idev_id with the seat owning @a wnd->orig_pos_id
     1184 * (the device that started the window move or resize).
     1185 *
     1186 * This is used to make sure that, when two seats focus the same window,
     1187 * only devices owned by the seat that started the resize or move can
     1188 * affect it. Otherwise moving the other pointer(s) would disrupt the
     1189 * resize or move operation.
     1190 *
     1191 * @param wnd Window (that is currently being resized or moved)
     1192 * @param idev_id Input device ID
     1193 * @return @c true iff idev_id is owned by the same seat as the input
     1194 *         device that started the resize or move
     1195 */
     1196bool ds_window_orig_seat(ds_window_t *wnd, sysarg_t idev_id)
     1197{
     1198        ds_seat_t *orig_seat;
     1199        ds_seat_t *seat;
     1200
     1201        /* Window must be in state such that wnd->orig_pos_id is valid */
     1202        assert(wnd->state == dsw_moving || wnd->state == dsw_resizing);
     1203
     1204        orig_seat = ds_display_seat_by_idev(wnd->display, wnd->orig_pos_id);
     1205        seat = ds_display_seat_by_idev(wnd->display, idev_id);
     1206
     1207        return seat == orig_seat;
     1208}
     1209
    8221210/** Window memory GC invalidate callback.
    8231211 *
Note: See TracChangeset for help on using the changeset viewer.