From de42a62f4e076df117449c1b3eeac51d7e5571a9 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Sat, 22 Jun 2002 03:23:02 +0000 Subject: [PATCH] Theme breakage! Themes have to implement "border" frames now, see Atlanta 2002-06-21 Havoc Pennington Theme breakage! Themes have to implement "border" frames now, see Atlanta for an example. Fixes #84285 * src/tools/metacity-window-demo.c (do_appwindow): add a border-only window * src/window.c (update_mwm_hints): read border only from the MWM hints * src/window.h (struct _MetaWindow): add border_only flag * src/core.c (meta_core_get_frame_type): report border type if required * src/common.h (enum): add META_FRAME_TYPE_BORDER --- ChangeLog | 18 ++++++++ src/common.h | 2 +- src/core.c | 23 ++++++---- src/frame.c | 39 ++++++++++------ src/theme-viewer.c | 38 ++++++++++++++++ src/theme.c | 6 ++- src/themes/Atlanta/metacity-theme-1.xml | 30 +++++++++++++ src/tools/metacity-window-demo.c | 59 ++++++++++++++++++++++++- src/window.c | 6 +++ src/window.h | 2 + 10 files changed, 198 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index b0689a273..0741b7e95 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2002-06-21 Havoc Pennington + + Theme breakage! Themes have to implement "border" frames + now, see Atlanta for an example. Fixes #84285 + + * src/tools/metacity-window-demo.c (do_appwindow): add a + border-only window + + * src/window.c (update_mwm_hints): read border only from the MWM + hints + + * src/window.h (struct _MetaWindow): add border_only flag + + * src/core.c (meta_core_get_frame_type): report border type if + required + + * src/common.h (enum): add META_FRAME_TYPE_BORDER + 2002-06-20 Mark McLoughlin * src/window.c: (meta_window_visible_on_workspace): sticky diff --git a/src/common.h b/src/common.h index 6287a946d..d87933342 100644 --- a/src/common.h +++ b/src/common.h @@ -141,7 +141,7 @@ typedef enum META_FRAME_TYPE_MODAL_DIALOG, META_FRAME_TYPE_UTILITY, META_FRAME_TYPE_MENU, - /* META_FRAME_TYPE_TOOLBAR, */ + META_FRAME_TYPE_BORDER, META_FRAME_TYPE_LAST } MetaFrameType; diff --git a/src/core.c b/src/core.c index 61c16b82b..6f0565e18 100644 --- a/src/core.c +++ b/src/core.c @@ -66,6 +66,7 @@ meta_core_get_frame_type (Display *xdisplay, { MetaDisplay *display; MetaWindow *window; + MetaFrameType base_type; display = meta_display_for_x_display (xdisplay); window = meta_display_lookup_x_window (display, frame_xwindow); @@ -73,26 +74,28 @@ meta_core_get_frame_type (Display *xdisplay, if (window == NULL || window->frame == NULL) meta_bug ("No such frame window 0x%lx!\n", frame_xwindow); + base_type = META_FRAME_TYPE_LAST; + switch (window->type) { case META_WINDOW_NORMAL: - return META_FRAME_TYPE_NORMAL; + base_type = META_FRAME_TYPE_NORMAL; break; case META_WINDOW_DIALOG: - return META_FRAME_TYPE_DIALOG; + base_type = META_FRAME_TYPE_DIALOG; break; case META_WINDOW_MODAL_DIALOG: - return META_FRAME_TYPE_MODAL_DIALOG; + base_type = META_FRAME_TYPE_MODAL_DIALOG; break; case META_WINDOW_MENU: - return META_FRAME_TYPE_MENU; + base_type = META_FRAME_TYPE_MENU; break; case META_WINDOW_UTILITY: - return META_FRAME_TYPE_UTILITY; + base_type = META_FRAME_TYPE_UTILITY; break; case META_WINDOW_DESKTOP: @@ -100,12 +103,16 @@ meta_core_get_frame_type (Display *xdisplay, case META_WINDOW_TOOLBAR: case META_WINDOW_SPLASHSCREEN: /* No frame */ - return META_FRAME_TYPE_LAST; + base_type = META_FRAME_TYPE_LAST; break; } - g_assert_not_reached (); - return META_FRAME_TYPE_LAST; + if (base_type == META_FRAME_TYPE_LAST) + return META_FRAME_TYPE_LAST; /* can't add border if undecorated */ + else if (window->border_only) + return META_FRAME_TYPE_BORDER; /* override base frame type */ + else + return base_type; } GdkPixbuf* diff --git a/src/frame.c b/src/frame.c index b823973c7..92628805f 100644 --- a/src/frame.c +++ b/src/frame.c @@ -203,24 +203,35 @@ MetaFrameFlags meta_frame_get_flags (MetaFrame *frame) { MetaFrameFlags flags; - - flags = META_FRAME_ALLOWS_MENU; - - if (frame->window->has_close_func) - flags |= META_FRAME_ALLOWS_DELETE; - - if (frame->window->has_maximize_func) - flags |= META_FRAME_ALLOWS_MAXIMIZE; - if (frame->window->has_minimize_func) - flags |= META_FRAME_ALLOWS_MINIMIZE; - - if (frame->window->has_shade_func) - flags |= META_FRAME_ALLOWS_SHADE; + flags = 0; + if (frame->window->border_only) + { + ; /* FIXME this may disable the _function_ as well as decor + * in some cases, which is sort of wrong. + */ + } + else + { + flags |= META_FRAME_ALLOWS_MENU; + + if (frame->window->has_close_func) + flags |= META_FRAME_ALLOWS_DELETE; + + if (frame->window->has_maximize_func) + flags |= META_FRAME_ALLOWS_MAXIMIZE; + + if (frame->window->has_minimize_func) + flags |= META_FRAME_ALLOWS_MINIMIZE; + + if (frame->window->has_shade_func) + flags |= META_FRAME_ALLOWS_SHADE; + } + if (frame->window->has_move_func) flags |= META_FRAME_ALLOWS_MOVE; - + if (frame->window->has_resize_func && !frame->window->maximized && !frame->window->shaded) diff --git a/src/theme-viewer.c b/src/theme-viewer.c index 4aa88e0b6..5687a00cd 100644 --- a/src/theme-viewer.c +++ b/src/theme-viewer.c @@ -317,6 +317,36 @@ menu_contents (void) return frame; } +static GtkWidget* +border_only_contents (void) +{ + GtkWidget *event_box; + GtkWidget *vbox; + GtkWidget *w; + GdkColor color; + + event_box = gtk_event_box_new (); + + color.red = 40000; + color.green = 0; + color.blue = 40000; + gtk_widget_modify_bg (event_box, GTK_STATE_NORMAL, &color); + + vbox = gtk_vbox_new (FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 3); + + w = gtk_label_new ("Border-only window"); + gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0); + w = gtk_button_new_with_label ("Bar"); + gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0); + + gtk_container_add (GTK_CONTAINER (event_box), vbox); + + gtk_widget_show_all (event_box); + + return event_box; +} + static GtkWidget* get_window_contents (MetaFrameType type, const char **title) @@ -348,6 +378,11 @@ get_window_contents (MetaFrameType type, return menu_contents (); break; + case META_FRAME_TYPE_BORDER: + *title = "Border"; + return border_only_contents (); + break; + case META_FRAME_TYPE_LAST: g_assert_not_reached (); break; @@ -392,6 +427,9 @@ get_window_flags (MetaFrameType type) META_FRAME_ALLOWS_MAXIMIZE); break; + case META_FRAME_TYPE_BORDER: + break; + case META_FRAME_TYPE_LAST: g_assert_not_reached (); break; diff --git a/src/theme.c b/src/theme.c index 1ca8a5727..dd7d5b359 100644 --- a/src/theme.c +++ b/src/theme.c @@ -3690,7 +3690,7 @@ meta_frame_style_draw (MetaFrameStyle *style, { GdkRectangle rect; GdkRectangle combined_clip; - + switch ((MetaFramePiece) i) { case META_FRAME_PIECE_ENTIRE_BACKGROUND: @@ -5119,6 +5119,8 @@ meta_frame_type_from_string (const char *str) return META_FRAME_TYPE_UTILITY; else if (strcmp ("menu", str) == 0) return META_FRAME_TYPE_MENU; + else if (strcmp ("border", str) == 0) + return META_FRAME_TYPE_BORDER; #if 0 else if (strcmp ("toolbar", str) == 0) return META_FRAME_TYPE_TOOLBAR; @@ -5142,6 +5144,8 @@ meta_frame_type_to_string (MetaFrameType type) return "utility"; case META_FRAME_TYPE_MENU: return "menu"; + case META_FRAME_TYPE_BORDER: + return "border"; #if 0 case META_FRAME_TYPE_TOOLBAR: return "toolbar"; diff --git a/src/themes/Atlanta/metacity-theme-1.xml b/src/themes/Atlanta/metacity-theme-1.xml index 85b7f59c9..8d9fa5053 100644 --- a/src/themes/Atlanta/metacity-theme-1.xml +++ b/src/themes/Atlanta/metacity-theme-1.xml @@ -43,6 +43,19 @@ + + + + + + + + + + + + + @@ -274,6 +287,11 @@ + + + + + @@ -297,11 +315,23 @@ + + + + + + + + + + + + diff --git a/src/tools/metacity-window-demo.c b/src/tools/metacity-window-demo.c index 933840ec2..6afa569e7 100644 --- a/src/tools/metacity-window-demo.c +++ b/src/tools/metacity-window-demo.c @@ -151,6 +151,37 @@ set_gtk_window_type (GtkWindow *window, type); } +static void +set_gdk_window_border_only (GdkWindow *window) +{ + gdk_window_set_decorations (window, GDK_DECOR_BORDER); +} + +static void +on_realize_set_border_only (GtkWindow *window, + gpointer data) +{ + g_return_if_fail (GTK_WIDGET_REALIZED (window)); + + set_gdk_window_border_only (GTK_WIDGET (window)->window); +} + +static void +set_gtk_window_border_only (GtkWindow *window) +{ + g_signal_handlers_disconnect_by_func (G_OBJECT (window), + on_realize_set_border_only, + NULL); + + g_signal_connect_after (G_OBJECT (window), + "realize", + G_CALLBACK (on_realize_set_border_only), + NULL); + + if (GTK_WIDGET_REALIZED (window)) + set_gdk_window_border_only (GTK_WIDGET (window)->window); +} + int main (int argc, char **argv) { @@ -332,6 +363,31 @@ override_redirect_cb (gpointer callback_data, gtk_widget_show_all (window); } +static void +border_only_cb (gpointer callback_data, + guint callback_action, + GtkWidget *widget) +{ + GtkWidget *window; + GtkWidget *vbox; + GtkWidget *label; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + set_gtk_window_border_only (GTK_WINDOW (window)); + gtk_window_set_title (GTK_WINDOW (window), "Border only"); + + gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (callback_data)); + + vbox = gtk_vbox_new (FALSE, 0); + + gtk_container_add (GTK_CONTAINER (window), vbox); + + label = gtk_label_new ("This window is supposed to have a border but no titlebar."); + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); + + gtk_widget_show_all (window); +} + static void changing_icon_cb (gpointer callback_data, guint callback_action, @@ -567,7 +623,8 @@ static GtkItemFactoryEntry menu_items[] = { "/Windows/Des_ktop", NULL, desktop_cb, 0, NULL }, { "/Windows/Me_nu", NULL, menu_cb, 0, NULL }, { "/Windows/Tool_bar", NULL, toolbar_cb, 0, NULL }, - { "/Windows/Override Redirect", NULL, override_redirect_cb, 0, NULL } + { "/Windows/Override Redirect", NULL, override_redirect_cb, 0, NULL }, + { "/Windows/Border Only", NULL, border_only_cb, 0, NULL } }; static void diff --git a/src/window.c b/src/window.c index 0a7fbc05c..0c1d9fc76 100644 --- a/src/window.c +++ b/src/window.c @@ -363,6 +363,7 @@ meta_window_new (MetaDisplay *display, Window xwindow, window->unmaps_pending = 0; window->mwm_decorated = TRUE; + window->mwm_border_only = FALSE; window->mwm_has_close_func = TRUE; window->mwm_has_minimize_func = TRUE; window->mwm_has_maximize_func = TRUE; @@ -4091,6 +4092,7 @@ update_mwm_hints (MetaWindow *window) MotifWmHints *hints; window->mwm_decorated = TRUE; + window->mwm_border_only = FALSE; window->mwm_has_close_func = TRUE; window->mwm_has_minimize_func = TRUE; window->mwm_has_maximize_func = TRUE; @@ -4117,6 +4119,9 @@ update_mwm_hints (MetaWindow *window) if (hints->decorations == 0) window->mwm_decorated = FALSE; + /* some input methods use this */ + else if (hints->decorations == MWM_DECOR_BORDER) + window->mwm_border_only = TRUE; } else meta_verbose ("Decorations flag unset\n"); @@ -4903,6 +4908,7 @@ recalc_window_features (MetaWindow *window) { /* Use MWM hints initially */ window->decorated = window->mwm_decorated; + window->border_only = window->mwm_border_only; window->has_close_func = window->mwm_has_close_func; window->has_minimize_func = window->mwm_has_minimize_func; window->has_maximize_func = window->mwm_has_maximize_func; diff --git a/src/window.h b/src/window.h index f5580ae29..479467794 100644 --- a/src/window.h +++ b/src/window.h @@ -131,6 +131,7 @@ struct _MetaWindow /* MWM hints about features of window */ guint mwm_decorated : 1; + guint mwm_border_only : 1; guint mwm_has_close_func : 1; guint mwm_has_minimize_func : 1; guint mwm_has_maximize_func : 1; @@ -139,6 +140,7 @@ struct _MetaWindow /* Computed features of window */ guint decorated : 1; + guint border_only : 1; guint always_sticky : 1; guint has_close_func : 1; guint has_minimize_func : 1;