The Gtk3 popovers look very nice and support adding gtk box as child.
But GtkPopover does not have it's own window like GtkMenu to be used as a stand-alone. So I figured there has to be a window where popover will be drawn.
In a panel plugin there is not enough place for popover to be drawn. So, bummer.
However it will work if a new window is created. Later I can position that window next to the panel plugin. I was also able to simulate GtkMenu behaviour where standalone popover will be closed if clicked outside it.
Now the arrows.
The popovers have the arrow and, when attached to a widget, popover's arrow points in the direction of that widget.
But, in the case of panel plugins, that arrow should be pointing to a widget that is outside of the window.
I was thinking about using dummy widgets like 1x1 pixel transparent image. Put them all around the window and then when figuring out where the button is and how the panel is oriented, attach a popover to the appropriate dummy widget.
This is a stand-alone GtkPopover:
Code: Select all
#include <gtk/gtk.h>
/* save this file as standalone-popover.c
create a 1x1 pixel transparent png image in the same folder
and name it dummy.png
compile with:
gcc standalone-popover.c -o standalone-popover `pkg-config --cflags --libs gtk+-3.0`
*/
#define DUMMY_PNG "dummy.png"
void destroy(GtkWidget* widget, gpointer data)
{
gtk_main_quit();
}
int main(int argc, char* argv[])
{
GtkWidget *window;
GtkWidget *popover;
GtkWidget *dummy_png_top_left;
GtkWidget *dummy_png_top_center;
GtkWidget *dummy_png_top_right;
GtkWidget *box;
GtkWidget *dummy_box_top;
GtkWidget *label;
GtkWidget *button;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_type_hint (GTK_WINDOW(window),
GDK_WINDOW_TYPE_HINT_POPUP_MENU);
gtk_widget_set_size_request(window, 250, 220);
gtk_window_set_resizable (GTK_WINDOW(window), TRUE);
gtk_window_set_keep_above (GTK_WINDOW (window), TRUE);
gtk_window_stick (GTK_WINDOW (window));
gtk_window_set_decorated (GTK_WINDOW(window), FALSE);
gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE);
gtk_widget_set_events (window, GDK_FOCUS_CHANGE_MASK);
g_signal_connect(window, "destroy",
G_CALLBACK(destroy), NULL);
g_signal_connect (G_OBJECT (GTK_WINDOW (window)),
"focus-out-event",
G_CALLBACK (destroy),
NULL);
gtk_window_present (GTK_WINDOW(window));
gtk_container_set_border_width(GTK_CONTAINER(window), 20);
dummy_png_top_left = gtk_image_new_from_file (DUMMY_PNG);
dummy_png_top_center = gtk_image_new_from_file (DUMMY_PNG);
dummy_png_top_right = gtk_image_new_from_file (DUMMY_PNG);
dummy_box_top = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_set_homogeneous (GTK_BOX (dummy_box_top), TRUE);
gtk_box_pack_start (GTK_BOX(dummy_box_top), dummy_png_top_left, TRUE, FALSE, 0);
gtk_box_pack_start (GTK_BOX(dummy_box_top), dummy_png_top_center, TRUE, FALSE, 0);
gtk_box_pack_start (GTK_BOX(dummy_box_top), dummy_png_top_right, TRUE, FALSE, 0);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
gtk_widget_show(dummy_png_top_left);
gtk_widget_show(dummy_png_top_center);
gtk_widget_show(dummy_png_top_right);
label = gtk_label_new ("Standalone GtkPopover");
button = gtk_button_new_with_label("OK");
gtk_box_pack_start (GTK_BOX(box), dummy_box_top, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX(box), label, TRUE, FALSE, 10);
gtk_box_pack_start (GTK_BOX(box), button, TRUE, FALSE, 10);
/* here we use the dummy widget to position the popover arrows */
popover = gtk_popover_new(dummy_png_top_center);
gtk_container_add(GTK_CONTAINER(window), popover);
gtk_container_add(GTK_CONTAINER(popover), box);
gtk_popover_set_modal(GTK_POPOVER(popover), FALSE);
g_signal_connect(G_OBJECT(button),
"clicked",
G_CALLBACK(destroy),
window);
gtk_widget_show_all(window);
/* need this to focus a window */
gtk_window_present_with_time(GTK_WINDOW(window),GDK_CURRENT_TIME);
gtk_window_activate_focus (GTK_WINDOW (window));
gtk_widget_grab_focus(GTK_WIDGET(window));
gtk_main();
return 0;
}
I also tried this with the xfce plugin.
https://m.youtube.com/watch?v=eXZzwDDQlZ8
Aligning the arrow properly with the panel plugin looks tricky right now.
Please let me know if someone has a better or easier way.