Changeset 1b92d4b in mainline for uspace/app/taskbar/wndlist.c


Ignore:
Timestamp:
2022-11-01T13:22:48Z (18 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fc00f0d
Parents:
913add60
git-author:
Jiri Svoboda <jiri@…> (2022-10-31 18:22:34)
git-committer:
Jiri Svoboda <jiri@…> (2022-11-01 13:22:48)
Message:

Update window buttons based on window added/removed events

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/taskbar/wndlist.c

    r913add60 r1b92d4b  
    3434
    3535#include <gfx/coord.h>
     36#include <stdbool.h>
    3637#include <stdio.h>
    3738#include <stdlib.h>
     
    4546#include "wndlist.h"
    4647
     48static void wndlist_wm_window_added(void *, sysarg_t);
     49static void wndlist_wm_window_removed(void *, sysarg_t);
     50
     51static wndmgt_cb_t wndlist_wndmgt_cb = {
     52        .window_added = wndlist_wm_window_added,
     53        .window_removed = wndlist_wm_window_removed
     54};
     55
    4756/** Create task bar window list.
    4857 *
    49  * @param res UI resource
     58 * @param window Containing window
    5059 * @param fixed Fixed layout to which buttons will be added
    5160 * @param wndmgt Window management service
     
    5362 * @return @c EOK on success or an error code
    5463 */
    55 errno_t wndlist_create(ui_resource_t *res, ui_fixed_t *fixed,
     64errno_t wndlist_create(ui_window_t *window, ui_fixed_t *fixed,
    5665    wndlist_t **rwndlist)
    5766{
     
    6574        }
    6675
    67         wndlist->res = res;
     76        wndlist->window = window;
    6877        wndlist->fixed = fixed;
    6978        list_initialize(&wndlist->entries);
     
    7786 *
    7887 * @param wndlist Window list
    79  * @param rwndlist Place to store pointer to new window list
    80  * @return @c EOK on success or an error code
    81  */
    82 errno_t wndlist_attach_wm(wndlist_t *wndlist, wndmgt_t *wndmgt)
     88 * @param wndmgt_svc Window management service name
     89 * @return @c EOK on success or an error code
     90 */
     91errno_t wndlist_open_wm(wndlist_t *wndlist, const char *wndmgt_svc)
    8392{
    8493        errno_t rc;
     
    8796        sysarg_t i;
    8897
    89         rc = wndmgt_get_window_list(wndmgt, &wlist);
     98        rc = wndmgt_open(wndmgt_svc, &wndlist_wndmgt_cb, (void *)wndlist,
     99            &wndlist->wndmgt);
     100        if (rc != EOK)
     101                goto error;
     102
     103        rc = wndmgt_get_window_list(wndlist->wndmgt, &wlist);
    90104        if (rc != EOK)
    91105                goto error;
    92106
    93107        for (i = 0; i < wlist->nwindows; i++) {
    94                 rc = wndmgt_get_window_info(wndmgt, wlist->windows[i],
     108                rc = wndmgt_get_window_info(wndlist->wndmgt, wlist->windows[i],
    95109                    &winfo);
    96110                if (rc != EOK)
    97111                        goto error;
    98112
    99                 rc = wndlist_append(wndlist, winfo->caption);
     113                rc = wndlist_append(wndlist, wlist->windows[i], winfo->caption,
     114                    false);
    100115                if (rc != EOK) {
    101116                        wndmgt_free_window_info(winfo);
     
    106121        }
    107122
    108         wndlist->wndmgt = wndmgt;
    109123        return EOK;
    110124error:
    111125        if (wlist != NULL)
    112126                wndmgt_free_window_list(wlist);
     127        if (wndlist->wndmgt != NULL) {
     128                wndmgt_close(wndlist->wndmgt);
     129                wndlist->wndmgt = NULL;
     130        }
    113131        return rc;
    114132}
     
    117135void wndlist_destroy(wndlist_t *wndlist)
    118136{
     137        wndlist_entry_t *entry;
     138
     139        /* Close window management service */
     140        if (wndlist->wndmgt)
     141                wndmgt_close(wndlist->wndmgt);
     142
     143        /* Destroy entries */
     144        entry = wndlist_first(wndlist);
     145        while (entry != NULL) {
     146                (void)wndlist_remove(wndlist, entry, false);
     147                entry = wndlist_first(wndlist);
     148        }
     149
    119150        free(wndlist);
    120151}
     
    123154 *
    124155 * @param wndlist Window list
     156 * @param wnd_id Window ID
    125157 * @param caption Entry caption
    126  * @return @c EOK on success or an error code
    127  */
    128 errno_t wndlist_append(wndlist_t *wndlist, const char *caption)
     158 * @param paint @c true to paint immediately
     159 * @return @c EOK on success or an error code
     160 */
     161errno_t wndlist_append(wndlist_t *wndlist, sysarg_t wnd_id,
     162    const char *caption, bool paint)
    129163{
    130164        wndlist_entry_t *entry = NULL;
    131         gfx_rect_t rect;
    132         size_t nentries;
     165        ui_resource_t *res;
    133166        errno_t rc;
    134 
    135         /* Number of existing entries */
    136         nentries = list_count(&wndlist->entries);
    137167
    138168        entry = calloc(1, sizeof(wndlist_entry_t));
     
    142172        }
    143173
    144         rc = ui_pbutton_create(wndlist->res, caption, &entry->button);
    145         if (rc != EOK)
    146                 goto error;
    147 
    148         if (ui_resource_is_textmode(wndlist->res)) {
    149                 rect.p0.x = 17 * nentries + 9;
    150                 rect.p0.y = 0;
    151                 rect.p1.x = 17 * nentries + 25;
    152                 rect.p1.y = 1;
    153         } else {
    154                 rect.p0.x = 145 * nentries + 90;
    155                 rect.p0.y = 3;
    156                 rect.p1.x = 145 * nentries + 230;
    157                 rect.p1.y = 29;
    158         }
    159 
    160         ui_pbutton_set_rect(entry->button, &rect);
    161 
    162         rc = ui_fixed_add(wndlist->fixed, ui_pbutton_ctl(entry->button));
     174        entry->wnd_id = wnd_id;
     175        res = ui_window_get_res(wndlist->window);
     176
     177        rc = ui_pbutton_create(res, caption, &entry->button);
    163178        if (rc != EOK)
    164179                goto error;
     
    166181        entry->wndlist = wndlist;
    167182        list_append(&entry->lentries, &wndlist->entries);
     183
     184        /* Set the button rectangle */
     185        wndlist_set_entry_rect(wndlist, entry);
     186
     187        rc = ui_fixed_add(wndlist->fixed, ui_pbutton_ctl(entry->button));
     188        if (rc != EOK)
     189                goto error;
     190
     191        if (paint) {
     192                rc = ui_pbutton_paint(entry->button);
     193                if (rc != EOK)
     194                        goto error;
     195        }
    168196
    169197        return EOK;
     
    177205}
    178206
     207/** Remove entry from window list.
     208 *
     209 * @param wndlist Window list
     210 * @param entry Window list entry
     211 * @param paint @c true to repaint window list
     212 * @return @c EOK on success or an error code
     213 */
     214errno_t wndlist_remove(wndlist_t *wndlist, wndlist_entry_t *entry,
     215    bool paint)
     216{
     217        wndlist_entry_t *next;
     218        assert(entry->wndlist == wndlist);
     219
     220        next = wndlist_next(entry);
     221
     222        ui_fixed_remove(wndlist->fixed, ui_pbutton_ctl(entry->button));
     223        ui_pbutton_destroy(entry->button);
     224        list_remove(&entry->lentries);
     225        free(entry);
     226
     227        /* Update positions of the remaining entries */
     228        while (next != NULL) {
     229                wndlist_set_entry_rect(wndlist, next);
     230                next = wndlist_next(next);
     231        }
     232
     233        if (!paint)
     234                return EOK;
     235
     236        return wndlist_repaint(wndlist);
     237}
     238
     239/** Compute and set window list entry rectangle.
     240 *
     241 * Compute rectangle for window list entry and set it.
     242 *
     243 * @param wndlist Window list
     244 * @param entry Window list entry
     245 */
     246void wndlist_set_entry_rect(wndlist_t *wndlist, wndlist_entry_t *entry)
     247{
     248        wndlist_entry_t *e;
     249        gfx_rect_t rect;
     250        ui_resource_t *res;
     251        size_t idx;
     252
     253        /* Determine entry index */
     254        idx = 0;
     255        e = wndlist_first(wndlist);
     256        while (e != entry) {
     257                assert(e != NULL);
     258                e = wndlist_next(e);
     259                ++idx;
     260        }
     261
     262        res = ui_window_get_res(wndlist->window);
     263
     264        if (ui_resource_is_textmode(res)) {
     265                rect.p0.x = 17 * idx + 9;
     266                rect.p0.y = 0;
     267                rect.p1.x = 17 * idx + 25;
     268                rect.p1.y = 1;
     269        } else {
     270                rect.p0.x = 145 * idx + 90;
     271                rect.p0.y = 3;
     272                rect.p1.x = 145 * idx + 230;
     273                rect.p1.y = 29;
     274        }
     275
     276        ui_pbutton_set_rect(entry->button, &rect);
     277}
     278
     279/** Handle WM window added event.
     280 *
     281 * @param arg Argument (wndlist_t *)
     282 * @param wnd_id Window ID
     283 */
     284static void wndlist_wm_window_added(void *arg, sysarg_t wnd_id)
     285{
     286        wndlist_t *wndlist = (wndlist_t *)arg;
     287        wndmgt_window_info_t *winfo = NULL;
     288        errno_t rc;
     289
     290        rc = wndmgt_get_window_info(wndlist->wndmgt, wnd_id, &winfo);
     291        if (rc != EOK)
     292                goto error;
     293
     294        rc = wndlist_append(wndlist, wnd_id, winfo->caption, true);
     295        if (rc != EOK) {
     296                wndmgt_free_window_info(winfo);
     297                goto error;
     298        }
     299
     300        wndmgt_free_window_info(winfo);
     301        return;
     302error:
     303        if (winfo != NULL)
     304                wndmgt_free_window_info(winfo);
     305}
     306
     307/** Handle WM window removed event.
     308 *
     309 * @param arg Argument (wndlist_t *)
     310 * @param wnd_id Window ID
     311 */
     312static void wndlist_wm_window_removed(void *arg, sysarg_t wnd_id)
     313{
     314        wndlist_t *wndlist = (wndlist_t *)arg;
     315        wndlist_entry_t *entry;
     316
     317        printf("wm_window_removed: wndlist=%p wnd_id=%zu\n",
     318            (void *)wndlist, wnd_id);
     319
     320        entry = wndlist_entry_by_id(wndlist, wnd_id);
     321        if (entry == NULL)
     322                return;
     323
     324        (void) wndlist_remove(wndlist, entry, true);
     325}
     326
     327/** Find window list entry by ID.
     328 *
     329 * @param wndlist Window list
     330 * @param wnd_id Window ID
     331 * @return Window list entry on success or @c NULL if not found
     332 */
     333wndlist_entry_t *wndlist_entry_by_id(wndlist_t *wndlist, sysarg_t wnd_id)
     334{
     335        wndlist_entry_t *entry;
     336
     337        entry = wndlist_first(wndlist);
     338        while (entry != NULL) {
     339                if (entry->wnd_id == wnd_id)
     340                        return entry;
     341
     342                entry = wndlist_next(entry);
     343        }
     344
     345        return NULL;
     346}
     347
     348/** Get first window list entry.
     349 *
     350 * @param wndlist Window list
     351 * @return First entry or @c NULL if the list is empty
     352 */
     353wndlist_entry_t *wndlist_first(wndlist_t *wndlist)
     354{
     355        link_t *link;
     356
     357        link = list_first(&wndlist->entries);
     358        if (link == NULL)
     359                return NULL;
     360
     361        return list_get_instance(link, wndlist_entry_t, lentries);
     362}
     363
     364/** Get next window list entry.
     365 *
     366 * @param cur Current entry
     367 * @return Next entry or @c NULL if @a cur is the last entry
     368 */
     369wndlist_entry_t *wndlist_next(wndlist_entry_t *cur)
     370{
     371        link_t *link;
     372
     373        link = list_next(&cur->lentries, &cur->wndlist->entries);
     374        if (link == NULL)
     375                return NULL;
     376
     377        return list_get_instance(link, wndlist_entry_t, lentries);
     378}
     379
     380/** Repaint window list.
     381 *
     382 * @param wndlist Window list
     383 * @return @c EOK on success or an error code
     384 */
     385errno_t wndlist_repaint(wndlist_t *wndlist)
     386{
     387        return ui_window_paint(wndlist->window);
     388}
     389
    179390/** @}
    180391 */
Note: See TracChangeset for help on using the changeset viewer.