1
2 #include "jayatana-window.h"
3
jayatana_window_new()4 JAyatanaWindow *jayatana_window_new()
5 {
6 JAyatanaWindow *ret = (JAyatanaWindow *)g_malloc0(sizeof(JAyatanaWindow));
7 ret->menu_items = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref);
8 ret->menu_counter = 1;
9 return ret;
10 }
11
jayatana_window_copy(JAyatanaWindow * src)12 JAyatanaWindow *jayatana_window_copy(JAyatanaWindow *src)
13 {
14 JAyatanaWindow *ret = (JAyatanaWindow *)g_malloc0(sizeof(JAyatanaWindow));
15 ret->windowXID = src->windowXID;
16 ret->globalThat = src->globalThat;
17 ret->menu_counter = src->menu_counter;
18
19 ret->windowXIDPath = g_strdup(src->windowXIDPath);
20 ret->gdBusProxyRegistered = src->gdBusProxyRegistered;
21 ret->gBusWatcher = src->gBusWatcher;
22 ret->dbBusProxy = G_DBUS_PROXY(g_object_ref(src->dbBusProxy));
23 ret->dbBusProxyCallSync = g_variant_ref(src->dbBusProxyCallSync);
24
25 ret->dbusMenuServer = DBUSMENU_SERVER(g_object_ref(src->dbusMenuServer));
26 ret->dbusMenuRoot = DBUSMENU_MENUITEM(g_object_ref(src->dbusMenuRoot));
27
28 ret->registerState = src->registerState;
29 ret->menu_items = g_hash_table_ref(src->menu_items);
30 return ret;
31 }
32
jayatana_window_free(JAyatanaWindow * window)33 void jayatana_window_free(JAyatanaWindow *window)
34 {
35 if (window->gdBusProxyRegistered)
36 {
37 g_clear_pointer(&window->windowXIDPath, g_free);
38 g_clear_object(&window->dbBusProxy);
39 g_clear_pointer(&window->dbBusProxyCallSync, g_variant_unref);
40 g_clear_object(&window->dbusMenuServer);
41 g_clear_object(&window->dbusMenuRoot);
42 }
43 g_clear_pointer(&window->menu_items, g_hash_table_unref);
44 g_clear_pointer(&window, g_free);
45 }
46
47 G_DEFINE_BOXED_TYPE(JAyatanaWindow, jayatana_window, (GBoxedCopyFunc)jayatana_window_copy,
48 (GBoxedFreeFunc)jayatana_window_free)
49
50 extern void jayatana_item_activated(DbusmenuMenuitem *item, guint timestamp, gpointer user_data);
51 extern void jayatana_item_events(DbusmenuMenuitem *item, const char *event);
52 extern void jayatana_item_about_to_show(DbusmenuMenuitem *item);
53
jayatana_window_get_dbusmenu_item(JAyatanaWindow * win,jint id,const char * cclabel)54 DbusmenuMenuitem *jayatana_window_get_dbusmenu_item(JAyatanaWindow *win, jint id,
55 const char *cclabel)
56 {
57 DbusmenuMenuitem *it;
58 char *checksum = g_compute_checksum_for_data(G_CHECKSUM_SHA512,
59 (const unsigned char *)cclabel,
60 strlen(cclabel));
61 it = DBUSMENU_MENUITEM(g_hash_table_lookup(win->menu_items, checksum));
62 if (it == NULL)
63 {
64 it = dbusmenu_menuitem_new_with_id(id > 0 ? id : win->menu_counter++);
65 g_hash_table_insert(win->menu_items, checksum, it);
66 }
67 else
68 {
69 g_signal_handlers_disconnect_by_func(it, (gpointer)jayatana_item_activated, NULL);
70 g_signal_handlers_disconnect_by_func(it, (gpointer)jayatana_item_events, NULL);
71 g_signal_handlers_disconnect_by_func(it,
72 (gpointer)jayatana_item_about_to_show,
73 NULL);
74 }
75 return it;
76 }
77
jayatana_window_remove_unparented(JAyatanaWindow * win)78 void jayatana_window_remove_unparented(JAyatanaWindow *win)
79 {
80 GHashTableIter iter;
81 char *key;
82 DbusmenuMenuitem *value;
83 g_hash_table_iter_init(&iter, win->menu_items);
84 while (g_hash_table_iter_next(&iter, (void **)&key, (void **)&value))
85 {
86 if (dbusmenu_menuitem_get_parent(value) == NULL)
87 g_hash_table_iter_remove(&iter);
88 }
89 }
90