Changeset ee3b28a9 in mainline for uspace/lib


Ignore:
Timestamp:
2024-02-26T13:30:48Z (17 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
d92b8e8f
Parents:
90ba06c
git-author:
Jiri Svoboda <jiri@…> (2024-02-25 16:12:29)
git-committer:
Jiri Svoboda <jiri@…> (2024-02-26 13:30:48)
Message:

Notify taskbar when start menu changes

Location:
uspace/lib
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/tbarcfg/include/tbarcfg/tbarcfg.h

    r90ba06c ree3b28a9  
    4242#include <types/tbarcfg/tbarcfg.h>
    4343
     44#define TBARCFG_NOTIFY_DEFAULT "tbarcfg-notif"
     45
    4446extern errno_t tbarcfg_create(const char *, tbarcfg_t **);
    4547extern errno_t tbarcfg_open(const char *, tbarcfg_t **);
     
    6365extern errno_t smenu_entry_move_up(smenu_entry_t *);
    6466extern errno_t smenu_entry_move_down(smenu_entry_t *);
     67extern errno_t tbarcfg_listener_create(const char *, void (*)(void *),
     68    void *, tbarcfg_listener_t **);
     69extern void tbarcfg_listener_destroy(tbarcfg_listener_t *);
     70extern errno_t tbarcfg_notify(const char *);
    6571
    6672#endif
  • uspace/lib/tbarcfg/include/types/tbarcfg/tbarcfg.h

    r90ba06c ree3b28a9  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4343typedef struct smenu_entry smenu_entry_t;
    4444
     45struct tbarcfg_listener;
     46typedef struct tbarcfg_listener tbarcfg_listener_t;
     47
    4548#endif
    4649
  • uspace/lib/tbarcfg/private/tbarcfg.h

    r90ba06c ree3b28a9  
    7171};
    7272
     73/** Taskbar configuration listener */
     74typedef struct tbarcfg_listener {
     75        /** Notification callback */
     76        void (*cb)(void *);
     77        /** Callback argument */
     78        void *arg;
     79} tbarcfg_listener_t;
     80
    7381extern errno_t smenu_entry_new(tbarcfg_t *, sif_node_t *, const char *,
    7482    const char *, bool, smenu_entry_t **);
  • uspace/lib/tbarcfg/src/tbarcfg.c

    r90ba06c ree3b28a9  
    3434 */
    3535
     36#include <async.h>
    3637#include <errno.h>
    3738#include <sif.h>
     39#include <ipc/tbarcfg.h>
     40#include <loc.h>
     41#include <task.h>
    3842#include <tbarcfg/tbarcfg.h>
     43#include <stdio.h>
    3944#include <stdlib.h>
    4045#include <str.h>
    4146#include "../private/tbarcfg.h"
     47
     48static void tbarcfg_notify_conn(ipc_call_t *, void *);
    4249
    4350/** Create taskbar configuration.
     
    784791}
    785792
     793/** Create taskbar configuration listener.
     794 *
     795 * Listens for taskbar configuration change notifications.
     796 *
     797 * @param nchan Notification channel (TBARCFG_NOTIFY_DEFAULT)
     798 * @param rlst Place to store pointer to new listener
     799 * @return EOK on success or an error code
     800 */
     801errno_t tbarcfg_listener_create(const char *nchan, void (*cb)(void *),
     802    void *arg, tbarcfg_listener_t **rlst)
     803{
     804        tbarcfg_listener_t *lst;
     805        service_id_t svcid = 0;
     806        loc_srv_t *srv = NULL;
     807        task_id_t taskid;
     808        char *svcname = NULL;
     809        category_id_t catid;
     810        port_id_t port;
     811        int rv;
     812        errno_t rc;
     813
     814        lst = calloc(1, sizeof(tbarcfg_listener_t));
     815        if (lst == NULL)
     816                return ENOMEM;
     817
     818        lst->cb = cb;
     819        lst->arg = arg;
     820
     821        rc = async_create_port(INTERFACE_TBARCFG_NOTIFY,
     822            tbarcfg_notify_conn, (void *)lst, &port);
     823        if (rc != EOK)
     824                goto error;
     825
     826        rc = loc_server_register("tbarcfg-listener", &srv);
     827        if (rc != EOK)
     828                goto error;
     829
     830        taskid = task_get_id();
     831
     832        rv = asprintf(&svcname, "tbarcfg/%u", (unsigned)taskid);
     833        if (rv < 0) {
     834                rc = ENOMEM;
     835                goto error;
     836        }
     837
     838        rc = loc_service_register(srv, svcname, &svcid);
     839        if (rc != EOK)
     840                goto error;
     841
     842        rc = loc_category_get_id(nchan, &catid, 0);
     843        if (rc != EOK)
     844                goto error;
     845
     846        rc = loc_service_add_to_cat(srv, svcid, catid);
     847        if (rc != EOK)
     848                goto error;
     849
     850        *rlst = lst;
     851        return EOK;
     852error:
     853        if (svcid != 0)
     854                loc_service_unregister(srv, svcid);
     855        if (srv != NULL)
     856                loc_server_unregister(srv);
     857        if (svcname != NULL)
     858                free(svcname);
     859        return rc;
     860}
     861
     862/** Destroy taskbar configuration listener.
     863 *
     864 * @param lst Listener
     865 */
     866void tbarcfg_listener_destroy(tbarcfg_listener_t *lst)
     867{
     868        free(lst);
     869}
     870
     871/** Send taskbar configuration notification to a particular service ID.
     872 *
     873 * @param svcid Service ID
     874 * @return EOK on success or an error code
     875 */
     876static errno_t tbarcfg_notify_svc(service_id_t svcid)
     877{
     878        async_sess_t *sess;
     879        async_exch_t *exch;
     880        errno_t rc;
     881
     882        sess = loc_service_connect(svcid, INTERFACE_TBARCFG_NOTIFY, 0);
     883        if (sess == NULL)
     884                return EIO;
     885
     886        exch = async_exchange_begin(sess);
     887        rc = async_req_0_0(exch, TBARCFG_NOTIFY_NOTIFY);
     888        if (rc != EOK) {
     889                async_exchange_end(exch);
     890                async_hangup(sess);
     891                return rc;
     892        }
     893
     894        async_exchange_end(exch);
     895        async_hangup(sess);
     896        return EOK;
     897}
     898
     899/** Send taskbar configuration change notification.
     900 *
     901 * @param nchan Notification channel (TBARCFG_NOTIFY_DEFAULT)
     902 */
     903errno_t tbarcfg_notify(const char *nchan)
     904{
     905        errno_t rc;
     906        category_id_t catid;
     907        service_id_t *svcs = NULL;
     908        size_t count, i;
     909
     910        rc = loc_category_get_id(nchan, &catid, 0);
     911        if (rc != EOK)
     912                return rc;
     913
     914        rc = loc_category_get_svcs(catid, &svcs, &count);
     915        if (rc != EOK)
     916                return rc;
     917
     918        for (i = 0; i < count; i++) {
     919                rc = tbarcfg_notify_svc(svcs[i]);
     920                if (rc != EOK)
     921                        goto error;
     922        }
     923
     924        free(svcs);
     925        return EOK;
     926error:
     927        free(svcs);
     928        return rc;
     929}
     930
     931/** Taskbar configuration connection handler.
     932 *
     933 * @param icall Initial call
     934 * @param arg Argument (tbarcfg_listener_t *)
     935 */
     936static void tbarcfg_notify_conn(ipc_call_t *icall, void *arg)
     937{
     938        tbarcfg_listener_t *lst = (tbarcfg_listener_t *)arg;
     939
     940        /* Accept the connection */
     941        async_accept_0(icall);
     942
     943        while (true) {
     944                ipc_call_t call;
     945                async_get_call(&call);
     946                sysarg_t method = ipc_get_imethod(&call);
     947
     948                if (!method) {
     949                        /* The other side has hung up */
     950                        async_answer_0(&call, EOK);
     951                        return;
     952                }
     953
     954                switch (method) {
     955                case TBARCFG_NOTIFY_NOTIFY:
     956                        lst->cb(lst->arg);
     957                        async_answer_0(&call, EOK);
     958                        break;
     959                default:
     960                        async_answer_0(&call, EINVAL);
     961                }
     962        }
     963}
     964
    786965/** @}
    787966 */
  • uspace/lib/tbarcfg/test/tbarcfg.c

    r90ba06c ree3b28a9  
    3030#include <pcut/pcut.h>
    3131#include <tbarcfg/tbarcfg.h>
     32#include <stdbool.h>
    3233#include <stdio.h>
    3334
     
    3536
    3637PCUT_TEST_SUITE(tbarcfg);
     38
     39typedef struct {
     40        bool notified;
     41} tbarcfg_test_resp_t;
     42
     43static void test_cb(void *);
    3744
    3845/** Creating, opening and closing taskbar configuration */
     
    554561}
    555562
     563/** Notifications can be delivered from tbarcfg_notify() to a listener. */
     564PCUT_TEST(notify)
     565{
     566        errno_t rc;
     567        tbarcfg_listener_t *lst;
     568        tbarcfg_test_resp_t test_resp;
     569
     570        test_resp.notified = false;
     571
     572        printf("create listener resp=%p\n", (void *)&test_resp);
     573        rc = tbarcfg_listener_create(TBARCFG_NOTIFY_DEFAULT,
     574            test_cb, &test_resp, &lst);
     575        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     576
     577        rc = tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
     578        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     579
     580        PCUT_ASSERT_TRUE(test_resp.notified);
     581        tbarcfg_listener_destroy(lst);
     582}
     583
     584static void test_cb(void *arg)
     585{
     586        tbarcfg_test_resp_t *resp = (tbarcfg_test_resp_t *)arg;
     587
     588        printf("test_cb: executing resp=%p\n", (void *)resp);
     589        resp->notified = true;
     590}
     591
    556592PCUT_EXPORT(tbarcfg);
  • uspace/lib/ui/src/menuentry.c

    r90ba06c ree3b28a9  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    145145                return;
    146146
     147        mentry->menu->total_h -= ui_menu_entry_height(mentry);
     148        /* NOTE: max_caption_w/max_shortcut_w not updated (speed) */
     149
    147150        list_remove(&mentry->lentries);
     151
     152        /*
     153         * If we emptied the menu, reset accumulated dims so they
     154         * can be correctly calculated when (if) the menu is
     155         * re-populated.
     156         */
     157        if (list_empty(&mentry->menu->entries)) {
     158                mentry->menu->total_h = 0;
     159                mentry->menu->max_caption_w = 0;
     160                mentry->menu->max_shortcut_w = 0;
     161        }
     162
    148163        free(mentry->caption);
    149164        free(mentry);
Note: See TracChangeset for help on using the changeset viewer.