Place popup menus and other override-redirect windows on top of the panel

https://bugzilla.gnome.org/show_bug.cgi?id=633620
This commit is contained in:
Jasper St. Pierre 2013-02-12 16:00:41 -05:00
parent a4e70ba4ca
commit 22ddec46ab
3 changed files with 42 additions and 3 deletions

View File

@ -25,6 +25,17 @@ const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
const MESSAGE_TRAY_PRESSURE_THRESHOLD = 200; // pixels const MESSAGE_TRAY_PRESSURE_THRESHOLD = 200; // pixels
const MESSAGE_TRAY_PRESSURE_TIMEOUT = 3000; // ms const MESSAGE_TRAY_PRESSURE_TIMEOUT = 3000; // ms
function isPopupMetaWindow(actor) {
switch(actor.meta_window.get_window_type()) {
case Meta.WindowType.DROPDOWN_MENU:
case Meta.WindowType.POPUP_MENU:
case Meta.WindowType.COMBO:
return true;
default:
return false;
}
}
const MonitorConstraint = new Lang.Class({ const MonitorConstraint = new Lang.Class({
Name: 'MonitorConstraint', Name: 'MonitorConstraint',
Extends: Clutter.Constraint, Extends: Clutter.Constraint,
@ -126,6 +137,7 @@ const LayoutManager = new Lang.Class({
this._updateRegionIdle = 0; this._updateRegionIdle = 0;
this._trackedActors = []; this._trackedActors = [];
this._isPopupWindowVisible = false;
// Normally, the stage is always covered so Clutter doesn't need to clear // Normally, the stage is always covered so Clutter doesn't need to clear
// it; however it becomes visible during the startup animation // it; however it becomes visible during the startup animation
@ -158,8 +170,10 @@ const LayoutManager = new Lang.Class({
// the GDM greeter inside an X11 compositor, to do this at the end... // the GDM greeter inside an X11 compositor, to do this at the end...
// However, hiding this is necessary to avoid showing the background during // However, hiding this is necessary to avoid showing the background during
// the initial animation, before Gdm.LoginDialog covers everything // the initial animation, before Gdm.LoginDialog covers everything
if (Main.sessionMode.isGreeter) if (Main.sessionMode.isGreeter) {
global.window_group.hide(); global.window_group.hide();
global.top_window_group.hide();
}
global.stage.remove_actor(global.overlay_group); global.stage.remove_actor(global.overlay_group);
this.uiGroup.add_actor(global.overlay_group); this.uiGroup.add_actor(global.overlay_group);
@ -190,6 +204,9 @@ const LayoutManager = new Lang.Class({
this.addChrome(this.keyboardBox); this.addChrome(this.keyboardBox);
this._keyboardHeightNotifyId = 0; this._keyboardHeightNotifyId = 0;
global.stage.remove_actor(global.top_window_group);
this.uiGroup.add_actor(global.top_window_group);
// Need to update struts on new workspaces when they are added // Need to update struts on new workspaces when they are added
global.screen.connect('notify::n-workspaces', global.screen.connect('notify::n-workspaces',
Lang.bind(this, this._queueUpdateRegions)); Lang.bind(this, this._queueUpdateRegions));
@ -801,6 +818,9 @@ const LayoutManager = new Lang.Class({
} }
} }
if (!changed && (this._isPopupWindowVisible != global.top_window_group.get_children().some(isPopupMetaWindow)))
changed = true;
if (changed) { if (changed) {
this._updateVisibility(); this._updateVisibility();
this._queueUpdateRegions(); this._queueUpdateRegions();
@ -819,9 +839,12 @@ const LayoutManager = new Lang.Class({
delete this._updateRegionIdle; delete this._updateRegionIdle;
} }
let isPopupMenuVisible = global.top_window_group.get_children().some(isPopupMetaWindow);
let wantsInputRegion = !isPopupMenuVisible;
for (i = 0; i < this._trackedActors.length; i++) { for (i = 0; i < this._trackedActors.length; i++) {
let actorData = this._trackedActors[i]; let actorData = this._trackedActors[i];
if (!actorData.affectsInputRegion && !actorData.affectsStruts) if (!(actorData.affectsInputRegion && wantsInputRegion) && !actorData.affectsStruts)
continue; continue;
let [x, y] = actorData.actor.get_transformed_position(); let [x, y] = actorData.actor.get_transformed_position();
@ -831,7 +854,7 @@ const LayoutManager = new Lang.Class({
w = Math.round(w); w = Math.round(w);
h = Math.round(h); h = Math.round(h);
if (actorData.affectsInputRegion) { if (actorData.affectsInputRegion && wantsInputRegion) {
let rect = new Meta.Rectangle({ x: x, y: y, width: w, height: h}); let rect = new Meta.Rectangle({ x: x, y: y, width: w, height: h});
if (actorData.actor.get_paint_visibility() && if (actorData.actor.get_paint_visibility() &&
@ -914,6 +937,7 @@ const LayoutManager = new Lang.Class({
} }
global.set_stage_input_region(rects); global.set_stage_input_region(rects);
this._isPopupWindowVisible = isPopupMenuVisible;
let screen = global.screen; let screen = global.screen;
for (let w = 0; w < screen.n_workspaces; w++) { for (let w = 0; w < screen.n_workspaces; w++) {

View File

@ -476,6 +476,7 @@ const Overview = new Lang.Class({
// Disable unredirection while in the overview // Disable unredirection while in the overview
Meta.disable_unredirect_for_screen(global.screen); Meta.disable_unredirect_for_screen(global.screen);
global.window_group.hide(); global.window_group.hide();
global.top_window_group.hide();
this._overview.show(); this._overview.show();
this._background.show(); this._background.show();
this._viewSelector.show(); this._viewSelector.show();
@ -643,6 +644,7 @@ const Overview = new Lang.Class({
Meta.enable_unredirect_for_screen(global.screen); Meta.enable_unredirect_for_screen(global.screen);
global.window_group.show(); global.window_group.show();
global.top_window_group.show();
this._viewSelector.hide(); this._viewSelector.hide();
this._desktopFade.hide(); this._desktopFade.hide();

View File

@ -107,6 +107,7 @@ enum {
PROP_STAGE, PROP_STAGE,
PROP_STAGE_INPUT_MODE, PROP_STAGE_INPUT_MODE,
PROP_WINDOW_GROUP, PROP_WINDOW_GROUP,
PROP_TOP_WINDOW_GROUP,
PROP_BACKGROUND_ACTOR, PROP_BACKGROUND_ACTOR,
PROP_WINDOW_MANAGER, PROP_WINDOW_MANAGER,
PROP_SETTINGS, PROP_SETTINGS,
@ -203,6 +204,9 @@ shell_global_get_property(GObject *object,
case PROP_WINDOW_GROUP: case PROP_WINDOW_GROUP:
g_value_set_object (value, meta_get_window_group_for_screen (global->meta_screen)); g_value_set_object (value, meta_get_window_group_for_screen (global->meta_screen));
break; break;
case PROP_TOP_WINDOW_GROUP:
g_value_set_object (value, meta_get_top_window_group_for_screen (global->meta_screen));
break;
case PROP_BACKGROUND_ACTOR: case PROP_BACKGROUND_ACTOR:
g_value_set_object (value, meta_get_background_actor_for_screen (global->meta_screen)); g_value_set_object (value, meta_get_background_actor_for_screen (global->meta_screen));
break; break;
@ -423,6 +427,15 @@ shell_global_class_init (ShellGlobalClass *klass)
"Actor holding window actors", "Actor holding window actors",
CLUTTER_TYPE_ACTOR, CLUTTER_TYPE_ACTOR,
G_PARAM_READABLE)); G_PARAM_READABLE));
g_object_class_install_property (gobject_class,
PROP_TOP_WINDOW_GROUP,
g_param_spec_object ("top-window-group",
"Top Window Group",
"Actor holding override-redirect windows",
CLUTTER_TYPE_ACTOR,
G_PARAM_READABLE));
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_BACKGROUND_ACTOR, PROP_BACKGROUND_ACTOR,
g_param_spec_object ("background-actor", g_param_spec_object ("background-actor",