Setting a custom GtkAccelLabel - c

I am trying to set a custom GtkAccelLabel to my GtkMenuItem, though I cant figure out how to use that widget ... for me just nothing is displayed.
Why are the following calls wrong / not sufficient ?
...
fileMi = gtk_menu_item_new_with_label("File");
label = gtk_accel_label_new ("Strg+X");
gtk_accel_label_set_accel_widget (label, quitMi);
...
Here a complete reproducer:
int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *menubar;
GtkWidget *fileMenu;
GtkWidget *fileMi;
GtkWidget *quitMi;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
gtk_window_set_title(GTK_WINDOW(window), "Simple menu");
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
GtkAccelGroup *accel_group;
// Create a GtkAccelGroup and add it to the window.
accel_group = gtk_accel_group_new ();
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
menubar = gtk_menu_bar_new();
fileMenu = gtk_menu_new();
fileMi = gtk_menu_item_new_with_label("File");
quitMi = gtk_menu_item_new_with_label("Quit");
gtk_menu_item_set_submenu(GTK_MENU_ITEM(fileMi), fileMenu);
gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), quitMi);
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), fileMi);
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
GtkWidget *label = gtk_accel_label_new ("Strg+X");
gtk_accel_label_set_accel_widget (label, quitMi);
gtk_accel_label_refetch (label);
g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(quitMi), "activate",
G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}

Hah, I found a solution .. though no idea if it actually should be done like that.
The key is, that there is already a gtk_accel_label on the MenuItem, and I can modify it:
for (GList* lp = gtk_container_get_children (quitMi); lp != NULL; lp = lp->next)
{
if (GTK_IS_ACCEL_LABEL (lp->data))
gtk_accel_label_set_accel (lp->data, GDK_KEY_0, GDK_MOD1_MASK);
}

Related

How can I add GtkEventBox in scrolled windows layout?

I have a GTK+2 program which combining GtkScrolledWindow and GtkLayout. It works fine. But, I found if I put a GtkEvent object to GtkLayout, it will not display properly. Anybody knows why ? Thanks.
#include <gtk/gtk.h>
int main( int argc, char *argv[] )
{
GtkWidget *window, *button, *layout, *eventbox, *scrollwindow;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request (window, 150, 150);
button = gtk_button_new_with_label ("button");
layout = gtk_layout_new(NULL, NULL);
gtk_layout_set_size( GTK_LAYOUT(layout), 300, 300);
scrollwindow = gtk_scrolled_window_new(GTK_LAYOUT(layout)->hadjustment, GTK_LAYOUT(layout)->vadjustment);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_layout_put( GTK_LAYOUT(layout), button, 50, 250 );
/* uncomment to use eventbox
eventbox = gtk_event_box_new();
gtk_container_add( GTK_CONTAINER(eventbox), layout);
gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scrollwindow), eventbox);
*/
// comment this line when use eventbox
gtk_container_add( GTK_CONTAINER(scrollwindow), layout);
gtk_container_add((GtkContainer*)window, scrollwindow);
gtk_widget_show_all(window);
gtk_main ();
return 0;
}
The picture if the eventbox is used.
I found it does not have to use GtkEventBox here. The GtkLayout can capture events directly.
The following widgets do not have an associated window. So, It should be used with the GtkEventBox if you want to capture events.
GtkAlignment
GtkArrow
GtkBin
GtkBox
GtkImage
GtkItem
GtkLabel
GtkPaned
GtkPixmap
GtkScrolledWindow
GtkSeparator
GtkTable
GtkViewport
GtkAspectFrame
GtkFrame
GtkVPaned
GtkHPaned
GtkVBox
GtkHBox
GtkVSeparator
GtkHSeparator
The fixed program :
#include <gtk/gtk.h>
static gboolean button_press_event( GtkWidget *widget, GdkEventButton *event ) {
if (event->button == 1 ) printf("but down %i , %i\n", (int)event->x, (int)event->y);
return TRUE;
}
int main( int argc, char *argv[] )
{
GtkWidget *window, *button, *layout, *eventbox, *scrollwindow;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request (window, 150, 150);
button = gtk_button_new_with_label ("button");
layout = gtk_layout_new(NULL, NULL);
gtk_layout_set_size( GTK_LAYOUT(layout), 300, 300);
scrollwindow = gtk_scrolled_window_new(gtk_layout_get_hadjustment(layout), gtk_layout_get_vadjustment(layout));
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_layout_put( GTK_LAYOUT(layout), button, 50, 250 );
gtk_container_add( GTK_CONTAINER(scrollwindow), layout);
gtk_container_add(GTK_CONTAINER(window), scrollwindow);
g_signal_connect (layout, "button_press_event", G_CALLBACK (button_press_event), NULL);
gtk_widget_set_events(layout, GDK_EXPOSURE_MASK
| GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK
| GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
gtk_widget_show_all(window);
gtk_main ();
return 0;
}
The result of clicking on GtkLayout :

Make the menu items of menu created, functionable using GTK+

Here in this code I have created a menu bar and added menus and menu items to it...
But i dont know how to make the created menu items functionable... for eg: I want the 'Open' menu item of 'File' in the menu bar, open a file and display it...
I'm making a project on a Text Editor using GTK+ 3
#include <gtk/gtk.h>
GtkWidget *window;
GdkPixbuf *icon;
GtkWidget *vbox;
GtkWidget *menubar;
GtkWidget *fileMenu;
GtkWidget *fileMi;
GtkWidget *editMenu;
GtkWidget *editMi;
GtkWidget *searchMenu;
GtkWidget *searchMi;
GtkWidget *newMi;
GtkWidget *openMi;
GtkWidget *saveMi;
GtkWidget *saveasMi;
GtkWidget *quitMi;
GtkWidget *undoMi;
GtkWidget *redoMi;
GtkWidget *cutMi;
GtkWidget *copyMi;
GtkWidget *pasteMi;
GtkWidget *fontMi;
GtkWidget *findMi;
GtkWidget *replaceMi;
GtkWidget *text_view;
GtkTextBuffer *buffer;
void txt(){
text_view = gtk_text_view_new ();
gtk_box_pack_start (GTK_BOX (vbox), text_view, TRUE, TRUE, 0);
}
GdkPixbuf *create_pixbuf (const gchar *filename)
{
GdkPixbuf *pixbuf;
GError *error = NULL;
pixbuf = gdk_pixbuf_new_from_file (filename, &error);
if (!pixbuf)
{
fprintf (stderr, "%s\n", error->message);
g_error_free (error);
}
return pixbuf;
}
static void fileOpen(GtkWidget *load, gpointer window)
{
GtkWidget *choose;
GtkFileChooserAction action= GTK_FILE_CHOOSER_ACTION_OPEN;
choose = gtk_file_chooser_dialog_new("Choose a file to open", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
if (gtk_dialog_run(GTK_DIALOG(choose)) == GTK_RESPONSE_ACCEPT)
{
char *path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(choose));
gtk_text_buffer_set_text(buffer, path, -1);
}
gtk_widget_destroy(choose);
}
static void fileSave(GtkWidget *save, gpointer window)
{
GtkWidget *saved;
saved = gtk_file_chooser_dialog_new("Choose a file to open", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
gtk_widget_show_all(saved);
gint resp = gtk_dialog_run(GTK_DIALOG(saved));
gtk_widget_destroy(saved);
}
int main (int argc, char *argv[])
{
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
icon = create_pixbuf ("Web.png");
gtk_window_set_title (GTK_WINDOW (window), "Write Pad");
gtk_window_set_default_size (GTK_WINDOW (window), 500, 400);
gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
gtk_window_set_icon (GTK_WINDOW (window), icon);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
menubar = gtk_menu_bar_new ();
fileMenu = gtk_menu_new ();
fileMi = gtk_menu_item_new_with_label ("File");
newMi = gtk_menu_item_new_with_label ("New");
openMi = gtk_menu_item_new_with_label ("Open");
saveMi = gtk_menu_item_new_with_label ("Save");
saveasMi = gtk_menu_item_new_with_label ("Save As");
quitMi = gtk_menu_item_new_with_label ("Quit");
menubar = gtk_menu_bar_new ();
editMenu = gtk_menu_new ();
editMi = gtk_menu_item_new_with_label ("Edit");
undoMi = gtk_menu_item_new_with_label ("Undo");
redoMi = gtk_menu_item_new_with_label ("Redo");
cutMi = gtk_menu_item_new_with_label ("Cut");
copyMi = gtk_menu_item_new_with_label ("Copy");
pasteMi = gtk_menu_item_new_with_label ("Paste");
fontMi = gtk_menu_item_new_with_label ("Font");
menubar = gtk_menu_bar_new ();
searchMenu = gtk_menu_new ();
searchMi = gtk_menu_item_new_with_label ("Search");
findMi = gtk_menu_item_new_with_label ("Find");
replaceMi = gtk_menu_item_new_with_label ("Replace");
gtk_menu_item_set_submenu (GTK_MENU_ITEM (fileMi), fileMenu);
gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), newMi);
gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), openMi);
gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), saveMi);
gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), saveasMi);
gtk_menu_shell_append (GTK_MENU_SHELL (fileMenu), quitMi);
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), fileMi);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (editMi), editMenu);
gtk_menu_shell_append(GTK_MENU_SHELL(editMenu), undoMi);
gtk_menu_shell_append(GTK_MENU_SHELL(editMenu), redoMi);
gtk_menu_shell_append(GTK_MENU_SHELL(editMenu), cutMi);
gtk_menu_shell_append(GTK_MENU_SHELL(editMenu), copyMi);
gtk_menu_shell_append (GTK_MENU_SHELL (editMenu), pasteMi);
gtk_menu_shell_append (GTK_MENU_SHELL (editMenu), fontMi);
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), editMi);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (searchMi), searchMenu);
gtk_menu_shell_append(GTK_MENU_SHELL(searchMenu), findMi);
gtk_menu_shell_append(GTK_MENU_SHELL(searchMenu), replaceMi);
gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0);
txt();
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (G_OBJECT (quitMi), "activate", G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (G_OBJECT (newMi), "activate", G_CALLBACK (main), NULL);
g_signal_connect(G_OBJECT (openMi), "activate", G_CALLBACK(fileOpen), NULL);
g_signal_connect(G_OBJECT (saveMi), "activate", G_CALLBACK(fileSave), NULL);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
Basically, the problem you have is caused by the fact that all of your widgets are global variables, but your fileOpen function takes a gpointer window argument:
//global
GtkWidget *window;
//gpointer window argument -> local variable, not global
static void fileOpen(GtkWidget *load, gpointer window)
{
GtkWidget *choose;
GtkFileChooserAction action= GTK_FILE_CHOOSER_ACTION_OPEN;
choose = gtk_file_chooser_dialog_new(
"Choose a file to open",
GTK_WINDOW(window),//window is not global, but function argument here !
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL
);
if (gtk_dialog_run(GTK_DIALOG(choose)) == GTK_RESPONSE_ACCEPT)
{
char *path = gtk_file_chooser_get_filename(
GTK_FILE_CHOOSER(choose)
);
gtk_text_buffer_set_text(buffer, path, -1);
}
gtk_widget_destroy(choose);
}
A quick fix would be to rename the argument to something like gp_data or something. A better fix would be to not use a global variable, and instead rely on the gpointer to pass on the objects you need:
g_signal_connect(
G_OBJECT (openMi),
"activate",
G_CALLBACK(fileOpen),
(gpointer)text_view // text_view and buffer needn't be global now
);
And then use the gpointer argument to get the window and anything else you might need. You could also use a custom struct or array of widgets to pass to the callback in case you need more stuff to work with, but in this case, you should be OK with just passing the text_view widget, and changing the callback to something like this:
static void fileOpen(GtkWidget *load, gpointer widget)
{
//get the buffer
GtkTextBuffer *buffer = gtk_text_view_get_buffer(
GTK_TEXT_VIEW (widget)
);
//get window from text_View widget passed to callback
//so window doesn't have to be global either...
GtkWidget *window = gtk_widget_get_toplevel(
widget
), *choose;
GtkFileChooserAction action= GTK_FILE_CHOOSER_ACTION_OPEN;
choose = gtk_file_chooser_dialog_new(
"Choose a file to open",
GTK_WINDOW(window),
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL
);
if (gtk_dialog_run(GTK_DIALOG(choose)) == GTK_RESPONSE_ACCEPT)
{
char *path = gtk_file_chooser_get_filename(
GTK_FILE_CHOOSER(choose)
);
gtk_text_buffer_set_text(buffer, path, -1);
}
gtk_widget_destroy(choose);
}
Note that I haven't tested this code, but this should be enough to get you started. You'll have to change the code you have a bit, but you should be able to get rid of all of those global variables simply by passing the right widget to the callbacks.
As always: Read the documentation, just adding the link to the answer for future reference

Menu doesn't display while creating it in GTK+ 3 C

Screenshot of the output
i am new with gtk+. while learning to create menus in gtk+ i simply copy paste the following code and when i run it....i don't know what is the problem but only it shows window. it does not show any menus or menu bar... help me if anyone has been through this problem...
#include <gtk/gtk.h>
GdkPixbuf *create_pixbuf(const gchar * filename)
{
GdkPixbuf *pixbuf;
GError *error = NULL;
pixbuf = gdk_pixbuf_new_from_file(filename, &error);
if (!pixbuf) {
fprintf(stderr, "%s\n", error->message);
g_error_free(error);
}
return pixbuf;
}
int main(int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *icon;
GtkWidget *vbox;
GtkWidget *menubar;
GtkWidget *fileMenu;
GtkWidget *fileMi;
GtkWidget *quitMi;
GtkWidget *text_view;
GtkWidget *buffer;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Write Pad");
gtk_window_set_default_size(GTK_WINDOW(window), 500, 400);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
icon = create_pixbuf("Web.png");
gtk_window_set_icon(GTK_WINDOW(window), icon);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
text_view = gtk_text_view_new ();
gtk_box_pack_start (GTK_BOX (vbox), text_view, 1, 1, 0);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
menubar = gtk_menu_bar_new();
fileMenu = gtk_menu_new();
fileMi = gtk_menu_item_new_with_label("File");
quitMi = gtk_menu_item_new_with_label("Quit");
gtk_menu_item_set_submenu(GTK_MENU_ITEM(fileMi), fileMenu);
gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), quitMi);
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), fileMi);
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(quitMi), "activate", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
There are a few problems with the code. All of the variables you declare use the GtkWidget * type, while the functions create_pixbuf and gtk_text_view_get_buffer return data of the GdkPixbuf * and GtkTextBuffer * types. You also use a deprecated function.
Moreover, you call the menu related functions after the GtkTextView related functions, thereby placing the menu at the bottom of the window.
Here is the working code:
#include <gtk/gtk.h>
GdkPixbuf *
create_pixbuf (const gchar *filename)
{
GdkPixbuf *pixbuf;
GError *error = NULL;
pixbuf = gdk_pixbuf_new_from_file (filename, &error);
if (!pixbuf) {
fprintf (stderr, "%s\n", error->message);
g_error_free (error);
}
return pixbuf;
}
int
main (int argc, char *argv[])
{
GtkWidget *window;
GdkPixbuf *icon;
GtkWidget *vbox;
GtkWidget *menubar;
GtkWidget *fileMenu;
GtkWidget *fileMi;
GtkWidget *quitMi;
GtkWidget *text_view;
GtkTextBuffer *buffer;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
icon = create_pixbuf ("Web.png");
gtk_window_set_title (GTK_WINDOW (window), "Write Pad");
gtk_window_set_default_size (GTK_WINDOW (window), 500, 400);
gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
gtk_window_set_icon (GTK_WINDOW (window), icon);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
menubar = gtk_menu_bar_new ();
fileMenu = gtk_menu_new ();
fileMi = gtk_menu_item_new_with_label ("File");
quitMi = gtk_menu_item_new_with_label ("Quit");
gtk_menu_item_set_submenu (GTK_MENU_ITEM (fileMi), fileMenu);
gtk_menu_shell_append (GTK_MENU_SHELL (fileMenu), quitMi);
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), fileMi);
gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0);
text_view = gtk_text_view_new ();
gtk_box_pack_start (GTK_BOX (vbox), text_view, TRUE, TRUE, 0);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (G_OBJECT (quitMi), "activate", G_CALLBACK (gtk_main_quit), NULL);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}

c GTK3 Text should scoll upward and not hide

here is my problem: I just put a gtk_text_view_new() in a gtk_scrolled_window_new(). Now when I write in the textField, at the end of the gtk_widget_set_size_request->high the text is hidden and the whole text does not scroll upwards as I want.
-> The textfield should automatically scroll upwards and show its last line.
#include <gtk/gtk.h>
int main(int argc, char **argv) {
gtk_init(&argc, &argv);
GtkWidget *window;
GtkWidget *myGrid;
GtkWidget *scollwindow;
GtkWidget *textField;
GtkTextBuffer *buffer;
GtkWidget *quitbutton;
//---------------------widgets-------------------------------
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
quitbutton = gtk_button_new_with_label("QUIT");
myGrid = gtk_grid_new ();
//---------------------textField-------------------------------
textField = gtk_text_view_new ();
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textField));
gtk_text_buffer_set_text (buffer, "Hello, this is some text, ", -1);
//---------------------insert textField in scrollwindow-------------------------------
scollwindow = gtk_scrolled_window_new (NULL,NULL);
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scollwindow), textField);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scollwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
//---------------------widgets size-------------------------------
gtk_widget_set_size_request (scollwindow, 200, 200);
gtk_widget_set_size_request (window, 200, 200);
//---------------------grid attache-------------------------------
gtk_grid_attach(GTK_GRID(myGrid), scollwindow, 0, 0, 1, 1);
gtk_grid_attach(GTK_GRID(myGrid), quitbutton, 0, 1, 1, 1);
//---------------------add to grid-------------------------------
gtk_container_add(GTK_CONTAINER(window), myGrid);
//---------------------signals-------------------------------
g_signal_connect(quitbutton, "clicked", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(window, "destroy", gtk_main_quit, NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
Got it, just change line " gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scollwindow), textField);" to "gtk_container_add (GTK_CONTAINER(scollwindow), textField);"

How to create gtk menu item with shortcut displayed?

I am trying to integrate appindicator with gtk menu.
I want some of menu items have shortcuts like here:
Unfortunately after adding accelerator to second menu item I still get item with no icon and no shortcut.
What I expect to see is a shortcut to the right of "item2".
int main (int argc, char **argv) {
gtk_init(&argc, &argv);
// main window
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "menu-with-shortcuts-window");
gtk_window_set_icon_name(GTK_WINDOW(window), "menu-with-shortcuts-icon");
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
// indicator
AppIndicator* indicator = app_indicator_new("menu-with-shortcuts-appindicator", "transmission-tray-icon", APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
// menu
GtkWidget* indicator_menu = gtk_menu_new();
GtkWidget* item1 = gtk_menu_item_new_with_label("item1");
gtk_menu_shell_append(GTK_MENU_SHELL(indicator_menu), item1);
g_signal_connect(item1, "activate", G_CALLBACK(Item1Clicked), NULL);
gtk_widget_show(item1);
GtkAccelGroup* accel_group = gtk_accel_group_new();
gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
GtkWidget* item2 = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, accel_group);
gtk_widget_add_accelerator(item2, "activate", accel_group, GDK_q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
gtk_menu_shell_append(GTK_MENU_SHELL(indicator_menu), item2);
g_signal_connect(item2, "activate", G_CALLBACK(Item2Clicked), NULL);
gtk_widget_show(item2);
app_indicator_set_status(indicator, APP_INDICATOR_STATUS_ACTIVE);
app_indicator_set_attention_icon(indicator, "menu-with-shortcuts-appindicator");
app_indicator_set_menu(indicator, GTK_MENU(indicator_menu));
gtk_widget_show_all(window);
gtk_main();
return 0;
}

Resources