[yocto] [matchbox-panel-2][PATCH 07/25] mb-panel: port to GTK+3
Jussi Kukkonen
jussi.kukkonen at intel.com
Tue May 3 04:30:26 PDT 2016
From: Ross Burton <ross.burton at intel.com>
Whilst porting to GTK+ 3 the layout model was simplified: panels are always
full-width and you just pick an edge and size. The panel is also multi-screen
and multi-monitor aware now.
---
matchbox-panel/mb-panel.c | 368 +++++++++++++++++++++++-----------------------
1 file changed, 187 insertions(+), 181 deletions(-)
diff --git a/matchbox-panel/mb-panel.c b/matchbox-panel/mb-panel.c
index 828a36d..1d6832f 100644
--- a/matchbox-panel/mb-panel.c
+++ b/matchbox-panel/mb-panel.c
@@ -1,9 +1,10 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/*
- * (C) 2006 OpenedHand Ltd.
+ * (C) 2006-2013 Intel Corp
*
- * Author: Jorn Baayen <jorn at openedhand.com>
+ * Authors: Ross Burton <ross.burton at intel.com>
+ * Jorn Baayen <jorn at openedhand.com>
*
* Licensed under the GPL v2 or greater.
*/
@@ -23,17 +24,16 @@
static GList *open_modules = NULL; /* List of open modules */
-/* Extra width and height to reserve for panel struts (see --reserve-extra) */
-static gint extra_width = 0;
-static gint extra_height = 0;
+enum {
+ ATOM_WM_STRUT_PARTIAL,
+ ATOM_MB_STATE,
+ ATOM_STATE_DOCT_TITLEBAR,
+ ATOM_DOCK_TITLEBAR_DESKTOP,
+ /* Counter */
+ ATOM_LAST
+};
-static gboolean snap_right = FALSE;
-static gboolean snap_bottom = FALSE;
-
-static gboolean center_vertical = FALSE;
-static gboolean center_horizontal = FALSE;
-
-static gboolean fullscreen = FALSE;
+static Atom atoms[ATOM_LAST];
/* Load applet @name with ID @id */
static GtkWidget *
@@ -132,63 +132,70 @@ load_applets (const char *applets_desc,
g_strfreev (applets);
}
-/* Set struts based on the window size and position */
static void
-set_struts (GtkWidget *window, gint x, gint y, gint w, gint h)
+set_struts (GtkWidget *window, GtkPositionType edge, int size)
{
- static Atom net_wm_strut_partial = None;
-
- guint32 struts [12];
- gint screen_width, screen_height;
- GdkScreen *screen;
-
- screen = gdk_screen_get_default ();
-
- screen_width = gdk_screen_get_width (screen);
- screen_height = gdk_screen_get_height (screen);
-
- /* left */
- struts[0] = x == 0 ? w + extra_width : 0;
- struts[4] = struts[0] ? y : 0;
- struts[5] = struts[0] ? y + h : 0;
+ Display *xdisplay;
+ int x, y, w, h;
+ struct {
+ long left;
+ long right;
+ long top;
+ long bottom;
+ long left_start_y;
+ long left_end_y;
+ long right_start_y;
+ long right_end_y;
+ long top_start_x;
+ long top_end_x;
+ long bottom_start_x;
+ long bottom_end_x;
+ } struts = { 0, };
+
+ xdisplay = GDK_SCREEN_XDISPLAY (gtk_widget_get_screen (window));
+ g_assert (xdisplay);
- /* right */
- struts[1] = x + w == screen_width ? w + extra_width: 0;
- struts[6] = struts[1] ? y : 0;
- struts[7] = struts[1] ? y + h : 0;
-
- /* top */
- struts[2] = y == 0 ? h + extra_height: 0;
- struts[8] = struts[2] ? x : 0;
- struts[9] = struts[2] ? x + w : 0;
+ gtk_window_get_position (GTK_WINDOW (window), &x, &y);
+ gtk_window_get_size (GTK_WINDOW (window), &w, &h);
- /* bottom */
- struts[3] = y + h == screen_height ? h + extra_height : 0;
- struts[10] = struts[3] ? x : 0;
- struts[11] = struts[3] ? x + w : 0;
+ switch (edge) {
+ case GTK_POS_LEFT:
+ struts.left = size;
+ struts.left_start_y = y;
+ struts.left_end_y = y + h;
+ break;
+ case GTK_POS_RIGHT:
+ struts.right = size;
+ struts.right_start_y = y;
+ struts.right_end_y = y + h;
+ break;
+ case GTK_POS_TOP:
+ struts.top = size;
+ struts.top_start_x = x;
+ struts.top_end_x = x + w;
+ break;
+ case GTK_POS_BOTTOM:
+ struts.bottom = size;
+ struts.bottom_start_x = x;
+ struts.bottom_end_x = x + w;
+ break;
+ }
gdk_error_trap_push ();
-
- if (!net_wm_strut_partial)
- net_wm_strut_partial = XInternAtom (GDK_DISPLAY () ,
- "_NET_WM_STRUT_PARTIAL",
- False);
-
- XChangeProperty (GDK_DISPLAY (),
- GDK_WINDOW_XID (window->window),
- net_wm_strut_partial, XA_CARDINAL, 32,
+ XChangeProperty (xdisplay,
+ GDK_WINDOW_XID (gtk_widget_get_window (window)),
+ atoms[ATOM_WM_STRUT_PARTIAL], XA_CARDINAL, 32,
PropModeReplace,
(guchar *) &struts, 12);
-
- gdk_error_trap_pop ();
+ gdk_error_trap_pop_ignored ();
}
+#if 0
static void
screen_size_changed_cb (GdkScreen *screen, GtkWidget *window)
{
gint x, y, w, h;
gint screen_width, screen_height;
-
gtk_window_get_position (GTK_WINDOW (window), &x, &y);
gtk_window_get_size (GTK_WINDOW (window), &w, &h);
@@ -232,6 +239,20 @@ screen_size_changed_cb (GdkScreen *screen, GtkWidget *window)
set_struts (window, x, y, w, h);
}
+#endif
+
+static void
+get_atoms (Display *xdisplay)
+{
+ static const char *names[] = {
+ "_NET_WM_STRUT_PARTIAL",
+ "_MB_WM_STATE",
+ "_MB_WM_STATE_DOCK_TITLEBAR",
+ "_MB_DOCK_TITLEBAR_SHOW_ON_DESKTOP"
+ };
+
+ XInternAtoms (xdisplay, (char**)names, G_N_ELEMENTS (names), False, atoms);
+}
int
main (int argc, char **argv)
@@ -239,54 +260,44 @@ main (int argc, char **argv)
GOptionContext *option_context;
GOptionGroup *option_group;
GError *error;
- char *geometry = NULL, *start_applets = NULL, *end_applets = NULL;
+ char *start_applets = NULL, *end_applets = NULL;
+ char *edge_string = NULL;
+ int size = DEFAULT_HEIGHT;
+ int screen_num = -1;
+ int monitor_num = -1;
+ GtkPositionType edge = GTK_POS_TOP;
GtkWidget *window, *box, *frame;
+ GdkDisplay *display;
GdkScreen *screen;
- int panel_width, panel_height;
- GtkOrientation orientation;
- gboolean want_titlebar = FALSE;
+ GtkOrientation orientation = GTK_ORIENTATION_HORIZONTAL;
+ gboolean in_titlebar = FALSE;
+ GdkRectangle screen_geom;
+ /* TODO: add these as groups (applets / position) */
GOptionEntry option_entries[] = {
- { "geometry", 0, 0, G_OPTION_ARG_STRING, &geometry,
- N_("Panel geometry"), N_("[WIDTH][xHEIGHT][{+-}X[{+-}Y]]") },
{ "start-applets", 0, 0, G_OPTION_ARG_STRING, &start_applets,
N_("Applets to pack at the start"), N_("APPLET[:APPLET_ID] ...") },
{ "end-applets", 0, 0, G_OPTION_ARG_STRING, &end_applets,
N_("Applets to pack at the end"), N_("APPLET[:APPLET_ID] ...") },
- { "titlebar", 0, 0, G_OPTION_ARG_NONE, &want_titlebar,
- N_("Display in window titlebar (If Matchbox theme supports)"),
- NULL },
- { "reserve-extra-width", 0, 0, G_OPTION_ARG_INT, &extra_width,
- N_("Extra width to reserve in panel strut in addittion to "
- "the window width"),
- N_("pixels")},
- { "reserve-extra-height", 0, 0, G_OPTION_ARG_INT, &extra_height,
- N_("Extra height to reserve in panel strut in addition to "
- "the window height"),
- N_("pixels")},
- { "center-horizontally", 0, 0, G_OPTION_ARG_NONE,
- ¢er_horizontal,
- N_("Center panel horizontally"),
- NULL },
- { "center-vertically", 0, 0, G_OPTION_ARG_NONE,
- ¢er_vertical,
- N_("Center panel vertically"),
- NULL },
- { "fullscreen", 0, 0, G_OPTION_ARG_NONE,
- &fullscreen,
- N_("Stretch panel to fullscreen in dominant direction "
- "(if used together with the --geometry options "
- "while the offset in the dominant direction will be "
- "ignored, it must not be specified with the + prefix, "
- "e.g., --geometry=200x32+0-0"),
- NULL },
+
+ { "screen", 'n', 0, G_OPTION_ARG_INT, &screen_num,
+ N_("Screen number"), N_("SCREEN") },
+ { "monitor", 'm', 0, G_OPTION_ARG_INT, &monitor_num,
+ N_("Monitor number"), N_("MONITOR") },
+
+ { "titlebar", 't', 0, G_OPTION_ARG_NONE, &in_titlebar,
+ N_("Display in window titlebar (with Matchbox theme support)"), NULL },
+ { "edge", 'e', 0, G_OPTION_ARG_STRING, &edge_string,
+ N_("Panel edge"), N_("TOP|BOTTON|LEFT|RIGHT") },
+ { "size", 's', 0, G_OPTION_ARG_INT, &size,
+ N_("Panel size"), N_("PIXELS")},
+
{ NULL }
};
/* Make sure that GModule is supported */
if (!g_module_supported ()) {
- g_warning (_("gmodule support not found. gmodule support is "
- "required for matchbox-panel to work"));
+ g_warning (_("GModule support not found, this is required for matchbox-panel to work"));
return -1;
}
@@ -316,44 +327,100 @@ main (int argc, char **argv)
g_option_context_free (option_context);
+ /* Can't be in the titlebar *and* on an edge, so check for this and exit */
+ if (in_titlebar && edge_string) {
+ g_printerr ("Cannot specify both --edge and --titlebar\n");
+ return 1;
+ }
+
+ if (edge_string) {
+ if (g_ascii_strcasecmp (edge_string, "top") == 0) {
+ edge = GTK_POS_TOP;
+ } else if (g_ascii_strcasecmp (edge_string, "bottom") == 0) {
+ edge = GTK_POS_BOTTOM;
+ } else if (g_ascii_strcasecmp (edge_string, "left") == 0) {
+ edge = GTK_POS_LEFT;
+ } else if (g_ascii_strcasecmp (edge_string, "right") == 0) {
+ edge = GTK_POS_RIGHT;
+ } else {
+ g_printerr ("Unparsable edge '%s', expecting top/bottom/left/right\n", edge_string);
+ return 1;
+ }
+ g_free (edge_string);
+ }
+
/* Set app name */
g_set_application_name (_("Matchbox Panel"));
+ display = gdk_display_get_default ();
+
+ get_atoms (GDK_DISPLAY_XDISPLAY (display));
+
+ if (screen_num != -1) {
+ screen = gdk_display_get_screen (display, screen_num);
+ } else {
+ screen = gdk_display_get_default_screen (display);
+ }
+
+ if (monitor_num == -1) {
+ monitor_num = gdk_screen_get_primary_monitor (screen);
+ }
+
+ /* Note that this is bare monitor geometry and not the work area, so
+ panels will overlap. */
+ gdk_screen_get_monitor_geometry (screen, monitor_num, &screen_geom);
+
/* Create window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-
gtk_widget_set_name (window, "MatchboxPanel");
-
- gtk_window_set_type_hint (GTK_WINDOW (window),
- GDK_WINDOW_TYPE_HINT_DOCK);
+ gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DOCK);
+ gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
/* No key focus please */
gtk_window_set_accept_focus (GTK_WINDOW (window), FALSE);
- /* Set default panel height */
- screen = gtk_window_get_screen (GTK_WINDOW (window));
- gtk_window_set_default_size (GTK_WINDOW (window),
- gdk_screen_get_width (screen),
- DEFAULT_HEIGHT);
-
- /* Parse geometry string */
- if (geometry) {
- if (!gtk_window_parse_geometry (GTK_WINDOW (window),
- geometry)) {
- g_warning ("Failed to parse geometry string");
-
- gtk_widget_destroy (window);
+ gtk_widget_realize (window);
- return 1;
+ /* Set size */
+ if (!in_titlebar) {
+ /* TODO: hook this up to GdkScreen:size-changed */
+
+ /* Orientation and size */
+ switch (edge) {
+ case GTK_POS_TOP:
+ case GTK_POS_BOTTOM:
+ orientation = GTK_ORIENTATION_HORIZONTAL;
+ gtk_widget_set_size_request (window,
+ screen_geom.width, size);
+ break;
+ case GTK_POS_LEFT:
+ case GTK_POS_RIGHT:
+ orientation = GTK_ORIENTATION_VERTICAL;
+ gtk_widget_set_size_request (window,
+ size, screen_geom.height);
+ break;
}
- }
- /* Determine window size */
- gtk_window_get_size (GTK_WINDOW (window), &panel_width, &panel_height);
+ /* Position */
+ switch (edge) {
+ case GTK_POS_TOP:
+ case GTK_POS_LEFT:
+ gtk_window_move (GTK_WINDOW (window),
+ screen_geom.x, screen_geom.y);
+ break;
+ case GTK_POS_RIGHT:
+ gtk_window_move (GTK_WINDOW (window),
+ screen_geom.x + screen_geom.width - size,
+ screen_geom.y);
+ break;
+ case GTK_POS_BOTTOM:
+ gtk_window_move (GTK_WINDOW (window),
+ screen_geom.x,
+ screen_geom.y + screen_geom.height - size);
+ }
- /* Force size */
- gtk_widget_set_size_request (window, panel_width, panel_height);
- gtk_window_resize (GTK_WINDOW (window), panel_width, panel_height);
+ set_struts (window, edge, size);
+ }
/* Add frame */
frame = gtk_frame_new (NULL);
@@ -362,91 +429,30 @@ main (int argc, char **argv)
gtk_widget_show (frame);
/* Is this a horizontal or a vertical layout? */
- if (panel_width >= panel_height) {
- orientation = GTK_ORIENTATION_HORIZONTAL;
-
+ if (orientation == GTK_ORIENTATION_HORIZONTAL) {
gtk_widget_set_name (frame, "MatchboxPanelFrameHorizontal");
-
- box = gtk_hbox_new (FALSE, 0);
} else {
- orientation = GTK_ORIENTATION_VERTICAL;
-
gtk_widget_set_name (frame, "MatchboxPanelFrameVertical");
-
- box = gtk_vbox_new (FALSE, 0);
}
+ box = gtk_box_new (orientation, 0);
gtk_container_add (GTK_CONTAINER (frame), box);
gtk_widget_show (box);
- gtk_widget_realize (window);
-
+#if 0
/* Do we want to display the panel in the Matchbox titlebar? */
- if (want_titlebar) {
- const char *names[] = {
- /* Set the Matchbox-specific window state */
- "_MB_WM_STATE",
- /* To the list of these atoms */
- "_MB_WM_STATE_DOCK_TITLEBAR",
- "_MB_DOCK_TITLEBAR_SHOW_ON_DESKTOP"
- };
- Atom atoms[G_N_ELEMENTS (names)];
-
- XInternAtoms (GDK_DISPLAY (), (char**)names,
- G_N_ELEMENTS (names), False, atoms);
-
- XChangeProperty (GDK_DISPLAY (),
- GDK_WINDOW_XID (window->window),
+ if (in_titlebar) {
+ XChangeProperty (GDK_SCREEN_XDISPLAY (screen),
+ GDK_WINDOW_XID (gtk_widget_get_window (window)),
atoms[0], XA_ATOM, 32,
PropModeReplace,
(unsigned char *) &atoms[1], 2);
} else {
- /* If we're not in a title bar, set the struts */
- gint screen_width = gdk_screen_get_width (screen);
- gint screen_height = gdk_screen_get_height (screen);
- gint x, y, w, h;
-
- gtk_window_get_position (GTK_WINDOW (window), &x, &y);
- gtk_window_get_size (GTK_WINDOW (window), &w, &h);
-
- if (fullscreen)
- {
- if (w > h)
- {
- w = screen_width;
- x = 0;
- }
- else
- {
- h = screen_height;
- y = 0;
- }
-
- gtk_widget_set_size_request (window, w, h);
- gtk_window_resize (GTK_WINDOW (window), w, h);
- }
-
- if (center_horizontal)
- x = (screen_width - w) / 2;
-
- if (center_vertical)
- y = (screen_height - h)/ 2;
-
- if (center_horizontal || center_vertical || fullscreen)
- gtk_window_move (GTK_WINDOW (window), x, y);
-
-
- if (x + w == screen_width)
- snap_right = TRUE;
-
- if (y + h == screen_height)
- snap_bottom = TRUE;
-
- set_struts (window, x, y, w, h);
g_signal_connect (screen, "size-changed",
G_CALLBACK (screen_size_changed_cb),
window);
}
+#endif
/* Load applets */
load_applets (start_applets,
--
2.8.1
More information about the yocto
mailing list