2b78d5bd5d
Fix panel, app switcher, and looking glass to limit themselves to the primary monitor, and run dialog to limit itself to the monitor containing the currently-focused window. The overview is also limited to the primary monitor now (with the other monitors being blacked out), although the workspaces within the overview are shaped like the full "screen" (the bounding box of all monitors). To be fixed later. https://bugzilla.gnome.org/show_bug.cgi?id=593060
215 lines
7.5 KiB
JavaScript
215 lines
7.5 KiB
JavaScript
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
|
|
const Big = imports.gi.Big;
|
|
const Clutter = imports.gi.Clutter;
|
|
const GLib = imports.gi.GLib;
|
|
const Lang = imports.lang;
|
|
const Mainloop = imports.mainloop;
|
|
const Meta = imports.gi.Meta;
|
|
const Shell = imports.gi.Shell;
|
|
const Signals = imports.signals;
|
|
const Gettext = imports.gettext.domain('gnome-shell');
|
|
const _ = Gettext.gettext;
|
|
|
|
const Lightbox = imports.ui.lightbox;
|
|
const Main = imports.ui.main;
|
|
|
|
const BOX_BACKGROUND_COLOR = new Clutter.Color();
|
|
BOX_BACKGROUND_COLOR.from_pixel(0x000000cc);
|
|
|
|
const BOX_TEXT_COLOR = new Clutter.Color();
|
|
BOX_TEXT_COLOR.from_pixel(0xffffffff);
|
|
|
|
const DIALOG_WIDTH = 320;
|
|
const DIALOG_PADDING = 6;
|
|
const ICON_SIZE = 24;
|
|
const ICON_BOX_SIZE = 36;
|
|
|
|
function RunDialog() {
|
|
this._init();
|
|
};
|
|
|
|
RunDialog.prototype = {
|
|
_init : function() {
|
|
this._isOpen = false;
|
|
|
|
let gconf = Shell.GConf.get_default();
|
|
gconf.connect('changed::development_tools', Lang.bind(this, function () {
|
|
this._enableInternalCommands = gconf.get_boolean('development_tools');
|
|
}));
|
|
this._enableInternalCommands = gconf.get_boolean('development_tools');
|
|
|
|
this._internalCommands = { 'lg':
|
|
Lang.bind(this, function() {
|
|
Main.createLookingGlass().open();
|
|
}),
|
|
|
|
'r': Lang.bind(this, function() {
|
|
global.reexec_self();
|
|
}),
|
|
|
|
// Developer brain backwards compatibility
|
|
'restart': Lang.bind(this, function() {
|
|
global.reexec_self();
|
|
}),
|
|
|
|
'debugexit': Lang.bind(this, function() {
|
|
Meta.exit(Meta.ExitCode.ERROR);
|
|
})
|
|
};
|
|
|
|
// All actors are inside _group. We create it initially
|
|
// hidden then show it in show()
|
|
this._group = new Clutter.Group({ visible: false,
|
|
x: 0,
|
|
y: 0,
|
|
width: global.screen_width,
|
|
height: global.screen_height });
|
|
global.stage.add_actor(this._group);
|
|
|
|
let lightbox = new Lightbox.Lightbox(this._group);
|
|
|
|
this._boxH = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
|
x_align: Big.BoxAlignment.CENTER,
|
|
y_align: Big.BoxAlignment.CENTER });
|
|
|
|
this._group.add_actor(this._boxH);
|
|
lightbox.highlight(this._boxH);
|
|
|
|
let boxV = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
|
y_align: Big.BoxAlignment.CENTER });
|
|
|
|
this._boxH.append(boxV, Big.BoxPackFlags.NONE);
|
|
|
|
|
|
let dialogBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
|
background_color: BOX_BACKGROUND_COLOR,
|
|
corner_radius: 4,
|
|
reactive: false,
|
|
padding: DIALOG_PADDING,
|
|
width: DIALOG_WIDTH });
|
|
|
|
this._boxH.append(dialogBox, Big.BoxPackFlags.NONE);
|
|
|
|
let label = new Clutter.Text({ color: BOX_TEXT_COLOR,
|
|
font_name: '18px Sans',
|
|
text: _("Please enter a command:") });
|
|
|
|
dialogBox.append(label, Big.BoxPackFlags.EXPAND);
|
|
|
|
this._entry = new Clutter.Text({ color: BOX_TEXT_COLOR,
|
|
font_name: '20px Sans Bold',
|
|
editable: true,
|
|
activatable: true,
|
|
singleLineMode: true });
|
|
|
|
dialogBox.append(this._entry, Big.BoxPackFlags.EXPAND);
|
|
|
|
this._errorBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
|
padding_top: DIALOG_PADDING });
|
|
|
|
dialogBox.append(this._errorBox, Big.BoxPackFlags.EXPAND);
|
|
|
|
let iconBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
|
y_align: Big.BoxAlignment.CENTER,
|
|
x_align: Big.BoxAlignment.CENTER,
|
|
width: ICON_BOX_SIZE,
|
|
height: ICON_BOX_SIZE });
|
|
|
|
this._errorBox.append(iconBox, Big.BoxPackFlags.NONE);
|
|
|
|
this._commandError = false;
|
|
|
|
let errorIcon = Shell.TextureCache.get_default().load_icon_name("gtk-dialog-error", ICON_SIZE);
|
|
iconBox.append(errorIcon, Big.BoxPackFlags.EXPAND);
|
|
|
|
this._errorMessage = new Clutter.Text({ color: BOX_TEXT_COLOR,
|
|
font_name: '18px Sans Bold',
|
|
line_wrap: true });
|
|
|
|
this._errorBox.append(this._errorMessage, Big.BoxPackFlags.EXPAND);
|
|
|
|
this._errorBox.hide();
|
|
|
|
this._entry.connect('activate', Lang.bind(this, function (o, e) {
|
|
this._run(o.get_text());
|
|
if (!this._commandError)
|
|
this.close();
|
|
}));
|
|
|
|
this._entry.connect('key-press-event', Lang.bind(this, function(o, e) {
|
|
let symbol = e.get_key_symbol();
|
|
if (symbol == Clutter.Escape) {
|
|
this.close();
|
|
return true;
|
|
}
|
|
return false;
|
|
}));
|
|
},
|
|
|
|
_run : function(command) {
|
|
let f;
|
|
if (this._enableInternalCommands)
|
|
f = this._internalCommands[command];
|
|
else
|
|
f = null;
|
|
if (f) {
|
|
f();
|
|
} else if (command) {
|
|
try {
|
|
this._commandError = false;
|
|
let [ok, len, args] = GLib.shell_parse_argv(command);
|
|
let p = new Shell.Process({'args' : args});
|
|
p.run();
|
|
} catch (e) {
|
|
this._commandError = true;
|
|
/*
|
|
* The exception contains an error string like:
|
|
* Error invoking Shell.run: Failed to execute child process "foo"
|
|
* (No such file or directory)
|
|
* We are only interested in the actual error, so parse that out.
|
|
*/
|
|
let m = /.+\((.+)\)/.exec(e);
|
|
let errorStr = "Execution of '" + command + "' failed:\n" + m[1];
|
|
this._errorMessage.set_text(errorStr);
|
|
this._errorBox.show();
|
|
}
|
|
}
|
|
},
|
|
|
|
open : function() {
|
|
if (this._isOpen) // Already shown
|
|
return;
|
|
|
|
if (!Main.pushModal(this._group))
|
|
return;
|
|
|
|
// Position the dialog on the current monitor
|
|
let monitor = global.get_focus_monitor();
|
|
|
|
this._boxH.set_position(monitor.x, monitor.y);
|
|
this._boxH.set_size(monitor.width, monitor.height);
|
|
|
|
this._isOpen = true;
|
|
this._group.show();
|
|
|
|
global.stage.set_key_focus(this._entry);
|
|
},
|
|
|
|
close : function() {
|
|
if (!this._isOpen)
|
|
return;
|
|
|
|
this._isOpen = false;
|
|
|
|
this._errorBox.hide();
|
|
this._commandError = false;
|
|
|
|
this._group.hide();
|
|
this._entry.text = '';
|
|
|
|
Main.popModal(this._group);
|
|
}
|
|
};
|
|
Signals.addSignalMethods(RunDialog.prototype);
|