38
38
#include "gen-application-menu-registrar.xml.h"
39
39
#include "gen-application-menu-renderer.xml.h"
40
40
#include "indicator-appmenu-marshal.h"
41
#include "window-menus.h"
41
#include "window-menu.h"
42
#include "window-menu-dbusmenu.h"
43
#include "window-menu-model.h"
42
44
#include "dbus-shared.h"
43
45
#include "gdk-get-func.h"
152
154
guint timestamp);
153
155
static void switch_default_app (IndicatorAppmenu * iapp,
154
WindowMenus * newdef,
155
157
BamfWindow * active_window);
156
158
static void find_desktop_windows (IndicatorAppmenu * iapp);
157
159
static void new_window (BamfMatcher * matcher,
160
162
static void old_window (BamfMatcher * matcher,
162
164
gpointer user_data);
163
static void window_entry_added (WindowMenus * mw,
164
IndicatorObjectEntry * entry,
166
static void window_entry_removed (WindowMenus * mw,
167
IndicatorObjectEntry * entry,
169
static void window_status_changed (WindowMenus * mw,
165
static void window_entry_added (WindowMenu * mw,
166
IndicatorObjectEntry * entry,
168
static void window_entry_removed (WindowMenu * mw,
169
IndicatorObjectEntry * entry,
171
static void window_status_changed (WindowMenu * mw,
170
172
DbusmenuStatus status,
171
173
IndicatorAppmenu * iapp);
172
static void window_show_menu (WindowMenus * mw,
174
static void window_show_menu (WindowMenu * mw,
173
175
IndicatorObjectEntry * entry,
175
177
gpointer user_data);
176
static void window_a11y_update (WindowMenus * mw,
178
static void window_a11y_update (WindowMenu * mw,
177
179
IndicatorObjectEntry * entry,
178
180
gpointer user_data);
179
181
static void active_window_changed (BamfMatcher * matcher,
589
591
gpointer pwm = g_hash_table_lookup(iapp->apps, GUINT_TO_POINTER(xid));
590
592
if (pwm != NULL) {
591
593
g_debug("Setting Desktop Menus to: %X", xid);
592
iapp->desktop_menu = WINDOW_MENUS(pwm);
594
iapp->desktop_menu = WINDOW_MENU(pwm);
643
645
gpointer pwm = g_hash_table_lookup(iapp->apps, GUINT_TO_POINTER(xid));
644
646
if (pwm != NULL) {
645
WindowMenus * wm = WINDOW_MENUS(pwm);
647
WindowMenu * wm = WINDOW_MENU(pwm);
646
648
iapp->desktop_menu = wm;
647
649
g_debug("Setting Desktop Menus to: %X", xid);
648
650
if (iapp->active_window == NULL && iapp->default_app == NULL) {
757
759
/* If we have a focused app with menus, use it's windows */
758
760
if (iapp->default_app != NULL) {
759
return window_menus_get_entries(iapp->default_app);
761
return window_menu_get_entries(iapp->default_app);
762
764
/* Else, let's go with desktop windows if there isn't a focused window */
814
816
IndicatorAppmenu * iapp = INDICATOR_APPMENU(io);
815
817
if (iapp->default_app != NULL) {
816
818
/* Find the location in the app */
817
count = window_menus_get_location(iapp->default_app, entry);
819
count = window_menu_get_location(iapp->default_app, entry);
818
820
} else if (iapp->active_window != NULL) {
819
821
/* Find the location in the window menus */
820
822
for (count = 0; count < iapp->window_menus->len; count++) {
830
832
/* Find the location in the desktop menu */
831
833
if (iapp->desktop_menu != NULL) {
832
count = window_menus_get_location(iapp->desktop_menu, entry);
834
count = window_menu_get_location(iapp->desktop_menu, entry);
842
844
return entry_activate_window(io, entry, 0, timestamp);
847
/* Find the BAMF Window that is associated with that XID. Unfortunately
848
this requires a bit of searching, don't do it too often */
850
xid_to_bamf_window (IndicatorAppmenu * iapp, guint xid)
852
GList * windows = bamf_matcher_get_windows(iapp->matcher);
854
BamfWindow * newwindow = NULL;
856
for (window = windows; window != NULL; window = g_list_next(window)) {
857
if (!BAMF_IS_WINDOW(window->data)) {
861
BamfWindow * testwindow = BAMF_WINDOW(window->data);
863
if (xid == bamf_window_get_xid(testwindow)) {
864
newwindow = testwindow;
868
g_list_free(windows);
845
873
/* Responds to a menuitem being activated on the panel. */
847
875
entry_activate_window (IndicatorObject * io, IndicatorObjectEntry * entry, guint windowid, guint timestamp)
851
879
/* We need to force a focus change in this case as we probably
852
880
just haven't gotten the signal from BAMF yet */
853
881
if (windowid != 0) {
854
GList * windows = bamf_matcher_get_windows(iapp->matcher);
856
BamfView * newwindow = NULL;
858
for (window = windows; window != NULL; window = g_list_next(window)) {
859
if (!BAMF_IS_WINDOW(window->data)) {
863
BamfWindow * testwindow = BAMF_WINDOW(window->data);
865
if (windowid == bamf_window_get_xid(testwindow)) {
866
newwindow = BAMF_VIEW(testwindow);
870
g_list_free(windows);
882
BamfView * newwindow = BAMF_VIEW(xid_to_bamf_window(iapp, windowid));
872
884
if (newwindow != NULL) {
873
885
active_window_changed(iapp->matcher, BAMF_VIEW(iapp->active_window), newwindow, iapp);
877
889
if (iapp->default_app != NULL) {
878
window_menus_entry_activate(iapp->default_app, entry, timestamp);
890
window_menu_entry_activate(iapp->default_app, entry, timestamp);
882
894
if (iapp->active_window == NULL) {
883
895
if (iapp->desktop_menu != NULL) {
884
window_menus_entry_activate(iapp->desktop_menu, entry, timestamp);
896
window_menu_entry_activate(iapp->desktop_menu, entry, timestamp);
969
981
/* Switch applications, remove all the entires for the previous
970
982
one and add them for the new application */
972
switch_default_app (IndicatorAppmenu * iapp, WindowMenus * newdef, BamfWindow * active_window)
984
switch_default_app (IndicatorAppmenu * iapp, WindowMenu * newdef, BamfWindow * active_window)
974
986
if (iapp->default_app == newdef && iapp->default_app != NULL) {
975
987
/* We've got an app with menus and it hasn't changed. */
1025
1037
/* Connect signals */
1026
1038
iapp->sig_entry_added = g_signal_connect(G_OBJECT(iapp->default_app),
1027
WINDOW_MENUS_SIGNAL_ENTRY_ADDED,
1039
WINDOW_MENU_SIGNAL_ENTRY_ADDED,
1028
1040
G_CALLBACK(window_entry_added),
1030
1042
iapp->sig_entry_removed = g_signal_connect(G_OBJECT(iapp->default_app),
1031
WINDOW_MENUS_SIGNAL_ENTRY_REMOVED,
1043
WINDOW_MENU_SIGNAL_ENTRY_REMOVED,
1032
1044
G_CALLBACK(window_entry_removed),
1034
1046
iapp->sig_status_changed = g_signal_connect(G_OBJECT(iapp->default_app),
1035
WINDOW_MENUS_SIGNAL_STATUS_CHANGED,
1047
WINDOW_MENU_SIGNAL_STATUS_CHANGED,
1036
1048
G_CALLBACK(window_status_changed),
1038
1050
iapp->sig_show_menu = g_signal_connect(G_OBJECT(iapp->default_app),
1039
WINDOW_MENUS_SIGNAL_SHOW_MENU,
1051
WINDOW_MENU_SIGNAL_SHOW_MENU,
1040
1052
G_CALLBACK(window_show_menu),
1042
1054
iapp->sig_a11y_update = g_signal_connect(G_OBJECT(iapp->default_app),
1043
WINDOW_MENUS_SIGNAL_A11Y_UPDATE,
1055
WINDOW_MENU_SIGNAL_A11Y_UPDATE,
1044
1056
G_CALLBACK(window_a11y_update),
1048
1060
/* show the entries that we're swapping in */
1049
1061
indicator_object_set_visible (INDICATOR_OBJECT(iapp), TRUE);
1051
/* Set up initial state for new entries if needed */
1063
/* Set up initial state for new entries if needed */
1052
1064
if (iapp->default_app != NULL &&
1053
window_menus_get_status (iapp->default_app) != DBUSMENU_STATUS_NORMAL) {
1065
window_menu_get_status (iapp->default_app) != WINDOW_MENU_STATUS_NORMAL) {
1054
1066
window_status_changed (iapp->default_app,
1055
window_menus_get_status (iapp->default_app),
1067
window_menu_get_status (iapp->default_app),
1092
1104
menus = g_hash_table_lookup(appmenu->apps, GUINT_TO_POINTER(xid));
1106
/* First look to see if we can get these from the
1107
GMenuModel access */
1108
if (menus == NULL) {
1109
gchar * uniquename = bamf_window_get_utf8_prop (window, "_GTK_UNIQUE_BUS_NAME");
1111
if (uniquename != NULL) {
1112
menus = WINDOW_MENU(window_menu_model_new(/* TODO */ NULL, window));
1114
g_hash_table_insert(appmenu->apps, GUINT_TO_POINTER(xid), menus);
1094
1120
if (menus == NULL) {
1095
1121
g_debug("Looking for parent window on XID %d", xid);
1096
1122
window = bamf_window_get_transient(window);
1116
1142
menus_destroyed (GObject * menus, gpointer user_data)
1118
1144
gboolean reload_menus = FALSE;
1119
WindowMenus * wm = WINDOW_MENUS(menus);
1145
WindowMenu * wm = WINDOW_MENU(menus);
1120
1146
IndicatorAppmenu * iapp = INDICATOR_APPMENU(user_data);
1122
guint32 xid = window_menus_get_xid(wm);
1148
guint32 xid = window_menu_get_xid(wm);
1123
1149
g_return_if_fail(xid != 0);
1125
1151
g_hash_table_steal(iapp->apps, GUINT_TO_POINTER(xid));
1158
1184
g_hash_table_remove(iapp->destruction_timers, GUINT_TO_POINTER(windowid));
1160
1186
if (g_hash_table_lookup(iapp->apps, GUINT_TO_POINTER(windowid)) == NULL && windowid != 0) {
1161
WindowMenus * wm = window_menus_new(windowid, sender, objectpath);
1187
WindowMenu * wm = WINDOW_MENU(window_menu_dbusmenu_new(windowid, sender, objectpath));
1162
1188
g_return_val_if_fail(wm != NULL, FALSE);
1164
1190
g_hash_table_insert(iapp->apps, GUINT_TO_POINTER(windowid), wm);
1233
1259
static GVariant *
1234
1260
get_menu_for_window (IndicatorAppmenu * iapp, guint windowid, GError ** error)
1236
WindowMenus * wm = NULL;
1262
WindowMenu * wm = NULL;
1238
1264
if (windowid == 0) {
1239
1265
wm = iapp->default_app;
1241
wm = WINDOW_MENUS(g_hash_table_lookup(iapp->apps, GUINT_TO_POINTER(windowid)));
1267
wm = WINDOW_MENU(g_hash_table_lookup(iapp->apps, GUINT_TO_POINTER(windowid)));
1244
1270
if (wm == NULL) {
1249
return g_variant_new("(so)", window_menus_get_address(wm),
1250
window_menus_get_path(wm));
1275
GVariantBuilder builder;
1276
g_variant_builder_init(&builder, G_VARIANT_TYPE_TUPLE);
1278
if (IS_WINDOW_MENU_DBUSMENU(wm)) {
1279
g_variant_builder_add_value(&builder, g_variant_new_string(window_menu_dbusmenu_get_address(WINDOW_MENU_DBUSMENU(wm))));
1280
g_variant_builder_add_value(&builder, g_variant_new_object_path(window_menu_dbusmenu_get_path(WINDOW_MENU_DBUSMENU(wm))));
1282
g_variant_builder_add_value(&builder, g_variant_new_string(""));
1283
g_variant_builder_add_value(&builder, g_variant_new_object_path("/"));
1286
return g_variant_builder_end(&builder);
1253
1289
/* Get all the menus we have */
1270
1306
GVariantBuilder tuple;
1271
1307
g_variant_builder_init(&tuple, G_VARIANT_TYPE_TUPLE);
1272
g_variant_builder_add_value(&tuple, g_variant_new_uint32(window_menus_get_xid(WINDOW_MENUS(hash_val))));
1273
g_variant_builder_add_value(&tuple, g_variant_new_string(window_menus_get_address(WINDOW_MENUS(hash_val))));
1274
g_variant_builder_add_value(&tuple, g_variant_new_object_path(window_menus_get_path(WINDOW_MENUS(hash_val))));
1308
g_variant_builder_add_value(&tuple, g_variant_new_uint32(window_menu_get_xid(WINDOW_MENU(hash_val))));
1310
if (IS_WINDOW_MENU_DBUSMENU(hash_val)) {
1311
g_variant_builder_add_value(&tuple, g_variant_new_string(window_menu_dbusmenu_get_address(WINDOW_MENU_DBUSMENU(hash_val))));
1312
g_variant_builder_add_value(&tuple, g_variant_new_object_path(window_menu_dbusmenu_get_path(WINDOW_MENU_DBUSMENU(hash_val))));
1314
g_variant_builder_add_value(&tuple, g_variant_new_string(""));
1315
g_variant_builder_add_value(&tuple, g_variant_new_object_path("/"));
1276
1318
g_variant_builder_add_value(&array, g_variant_builder_end(&tuple));
1325
1367
/* Pass up the entry added event */
1327
window_entry_added (WindowMenus * mw, IndicatorObjectEntry * entry, gpointer user_data)
1369
window_entry_added (WindowMenu * mw, IndicatorObjectEntry * entry, gpointer user_data)
1329
1371
g_signal_emit_by_name(G_OBJECT(user_data), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED, entry);
1333
1375
/* Pass up the entry removed event */
1335
window_entry_removed (WindowMenus * mw, IndicatorObjectEntry * entry, gpointer user_data)
1377
window_entry_removed (WindowMenu * mw, IndicatorObjectEntry * entry, gpointer user_data)
1337
1379
g_signal_emit_by_name(G_OBJECT(user_data), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED, entry);
1341
1383
/* Pass up the status changed event */
1343
window_status_changed (WindowMenus * mw, DbusmenuStatus status, IndicatorAppmenu * iapp)
1385
window_status_changed (WindowMenu * mw, DbusmenuStatus status, IndicatorAppmenu * iapp)
1345
1387
gboolean show_now = (status == DBUSMENU_STATUS_NOTICE);
1346
1388
GList * entry_head, * entries;
1358
1400
/* Pass up the show menu event */
1360
window_show_menu (WindowMenus * mw, IndicatorObjectEntry * entry, guint timestamp, gpointer user_data)
1402
window_show_menu (WindowMenu * mw, IndicatorObjectEntry * entry, guint timestamp, gpointer user_data)
1362
1404
g_signal_emit_by_name(G_OBJECT(user_data), INDICATOR_OBJECT_SIGNAL_MENU_SHOW, entry, timestamp);
1366
1408
/* Pass up the accessible string update */
1368
window_a11y_update (WindowMenus * mw, IndicatorObjectEntry * entry, gpointer user_data)
1410
window_a11y_update (WindowMenu * mw, IndicatorObjectEntry * entry, gpointer user_data)
1370
1412
g_signal_emit_by_name(G_OBJECT(user_data), INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE, entry);