From d9008054cf0a1a8823b4d5f73d1b5b0d5d52c4db Mon Sep 17 00:00:00 2001 From: Maxim Ermilov Date: Tue, 19 Jan 2010 20:59:29 +0300 Subject: [PATCH] Handle resolution changes Added signal 'screen-size-changed' to ShellGlobal. Connect to this signal in main.js and run the _relayout() method. If Overview or calendar are visible when this signal emit, they will be hiding. https://bugzilla.gnome.org/show_bug.cgi?id=584526 --- js/ui/main.js | 8 ++++ js/ui/overview.js | 2 + js/ui/panel.js | 8 ++++ src/shell-global.c | 96 +++++++++++++++++++++++++++++++++++++++++++++- src/shell-global.h | 1 + 5 files changed, 114 insertions(+), 1 deletion(-) diff --git a/js/ui/main.js b/js/ui/main.js index f8c95b364..81ab67268 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -135,6 +135,7 @@ function start() { }); _relayout(); + global.connect('screen-size-changed', _relayout); ExtensionSystem.init(); ExtensionSystem.loadExtensions(); @@ -199,6 +200,13 @@ function _relayout() { panel.actor.set_position(primary.x, primary.y); panel.actor.set_size(primary.width, Panel.PANEL_HEIGHT); overview.relayout(); + + // To avoid updating the position and size of the workspaces + // in the overview, we just hide the overview. The positions + // will be updated when it is next shown. We do the same for + // the calendar popdown. + overview.hide(); + panel.hideCalendar(); } // metacity-clutter currently uses the same prefs as plain metacity, diff --git a/js/ui/overview.js b/js/ui/overview.js index 6281dbfe4..2d41a4390 100644 --- a/js/ui/overview.js +++ b/js/ui/overview.js @@ -158,6 +158,8 @@ Overview.prototype = { relayout: function () { let primary = global.get_primary_monitor(); + this._recalculateGridSizes(); + this._group.set_position(primary.x, primary.y); let contentY = Panel.PANEL_HEIGHT; diff --git a/js/ui/panel.js b/js/ui/panel.js index 510a328ba..24e970436 100644 --- a/js/ui/panel.js +++ b/js/ui/panel.js @@ -398,6 +398,7 @@ Panel.prototype = { this._clock = new St.Label(); clockButton.set_child(this._clock); + this._clockButton = clockButton; this._calendarPopup = null; @@ -485,6 +486,13 @@ Panel.prototype = { this._updateClock(); }, + hideCalendar: function() { + if (this._calendarPopup != null) { + this._clockButton.checked = false; + this._calendarPopup.actor.hide(); + } + }, + startupAnimation: function() { this.actor.y = -this.actor.height; Tweener.addTween(this.actor, diff --git a/src/shell-global.c b/src/shell-global.c index 680e74664..71600ad62 100644 --- a/src/shell-global.c +++ b/src/shell-global.c @@ -6,6 +6,7 @@ #include "shell-wm.h" #include "display.h" +#include "util.h" #include #include #include @@ -17,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -53,6 +53,8 @@ struct _ShellGlobal { /* Displays the root window; see shell_global_create_root_pixmap_actor() */ ClutterActor *root_pixmap; + + gint last_change_screen_width, last_change_screen_height; }; enum { @@ -75,6 +77,7 @@ enum { PANEL_RUN_DIALOG, PANEL_MAIN_MENU, + SCREEN_SIZE_CHANGED, LAST_SIGNAL }; @@ -189,6 +192,9 @@ shell_global_init (ShellGlobal *global) global->root_pixmap = NULL; global->input_mode = SHELL_STAGE_INPUT_MODE_NORMAL; + + global->last_change_screen_width = 0; + global->last_change_screen_height = 0; } static void @@ -217,6 +223,15 @@ shell_global_class_init (ShellGlobalClass *klass) g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); + shell_global_signals[SCREEN_SIZE_CHANGED] = + g_signal_new ("screen-size-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ShellGlobalClass, screen_size_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + g_object_class_install_property (gobject_class, PROP_OVERLAY_GROUP, g_param_spec_object ("overlay-group", @@ -441,6 +456,77 @@ shell_global_get_windows (ShellGlobal *global) return mutter_plugin_get_windows (global->plugin); } +static gboolean +emit_screen_size_changed_cb (gpointer data) +{ + ShellGlobal *global = SHELL_GLOBAL (data); + + int width, height; + + mutter_plugin_query_screen_size (global->plugin, &width, &height); + + if (global->last_change_screen_width != width || global->last_change_screen_height != height) + { + g_signal_emit (G_OBJECT (global), shell_global_signals[SCREEN_SIZE_CHANGED], 0); + global->last_change_screen_width = width; + global->last_change_screen_height = height; + } + + return FALSE; +} + +static void +global_stage_notify_width (GObject *gobject, + GParamSpec *pspec, + gpointer data) +{ + ShellGlobal *global = SHELL_GLOBAL (data); + ClutterActor *stage = CLUTTER_ACTOR (gobject); + + if (global->root_pixmap) + clutter_actor_set_width (CLUTTER_ACTOR (global->root_pixmap), + clutter_actor_get_width (stage)); + g_object_notify (G_OBJECT (global), "screen-width"); + + meta_later_add (META_LATER_BEFORE_REDRAW, + emit_screen_size_changed_cb, + global, + NULL); +} + +static void +global_stage_notify_height (GObject *gobject, + GParamSpec *pspec, + gpointer data) +{ + ShellGlobal *global = SHELL_GLOBAL (data); + ClutterActor *stage = CLUTTER_ACTOR (gobject); + + if (global->root_pixmap) + clutter_actor_set_height (CLUTTER_ACTOR (global->root_pixmap), + clutter_actor_get_height (stage)); + g_object_notify (G_OBJECT (global), "screen-height"); + + meta_later_add (META_LATER_BEFORE_REDRAW, + emit_screen_size_changed_cb, + global, + NULL); +} + +static void +global_plugin_notify_screen (GObject *gobject, + GParamSpec *pspec, + gpointer data) +{ + ShellGlobal *global = SHELL_GLOBAL (data); + ClutterActor *stage = mutter_plugin_get_stage (MUTTER_PLUGIN (gobject)); + + g_signal_connect (stage, "notify::width", + G_CALLBACK (global_stage_notify_width), global); + g_signal_connect (stage, "notify::height", + G_CALLBACK (global_stage_notify_height), global); +} + void _shell_global_set_plugin (ShellGlobal *global, MutterPlugin *plugin) @@ -450,6 +536,14 @@ _shell_global_set_plugin (ShellGlobal *global, global->plugin = plugin; global->wm = shell_wm_new (plugin); + + /* At this point screen is NULL, so we can't yet do signal connections + * to the width and height; we wait until the screen property is set + * to do that. Note that this is a one time thing - screen will never + * change once first set. + */ + g_signal_connect (plugin, "notify::screen", + G_CALLBACK (global_plugin_notify_screen), global); } void diff --git a/src/shell-global.h b/src/shell-global.h index 12ebf5033..e59de7092 100644 --- a/src/shell-global.h +++ b/src/shell-global.h @@ -30,6 +30,7 @@ struct _ShellGlobalClass int timestamp); void (*panel_main_menu) (ShellGlobal *global, int timestamp); + void (*screen_size_changed) (ShellGlobal *global); }; GType shell_global_get_type (void) G_GNUC_CONST;