Compare commits

...

19 Commits

Author SHA1 Message Date
94d01bed12 build: Split out "private" sources variable that can be easily appended
Move the action muxing copy stuff in there.
2011-12-20 13:41:08 -05:00
9daf358122 action muxer: drop direct GDBusActionGroup use
We now have GRemoteActionGroup interface with the needed API,
implemented by GDBusActionGroup.

With the new API we could theoretically turn GActionMuxer itself into a
GRemoteActionGroup and expose the _full API to the shell so that the
timestamps could be passed from there.
2011-12-17 13:23:26 -05:00
b4b3f5a669 GActionMuxer: pass platform data
Pass the current timestamp as platform data when activating
an action. This is implemented slightly hacky, since we use
clutter_get_current_event_time() to get at the timestamp, but
the alternative is to expose g_action_muxer_activate_action_full
to js, which would be quite a bit more involved.
2011-12-16 23:39:14 -05:00
5290a9dd08 Add per-window actions
GTK+ also exports window-specific actions, by putting the object path
for the exported action group in the _DBUS_OBJECT_PATH X property.
We add this action group to the app's muxer with a 'win' prefix,
since that is what the exported menu expects. Whenever the focus
window changes, we update the window-specific actions of its
application, and emit notify::action-group to cause the app
menu to be updated.
2011-12-15 01:25:35 -05:00
ab4a7c5237 Another update for GLib API changes
GDBusActionGroup api has changed again, adapt to that.
Also, use a GActionMuxer to add the 'app.' prefix to actions,
instead of manually stripping it out of the action names.
In the future, the muxer will also contain per-window actions
with a 'win.' prefix.
2011-12-15 00:29:31 -05:00
95e5c5cfb1 Application Menu: watch for menu property changes
By the time the window is first mapped and the app menu button is
synced, we may not have finished reading the menu. In that case,
connect to notify::menu and update accordingly.
2011-12-08 21:55:51 +01:00
757fb5796e Application Menu: update for latest GMenu changes
GMenuProxy has been replaced by GDBusMenuModel, and the object path
has been moved (now needs to be retrieved from the AppMenu GApplication
property).
Update the test to prefix each action with "app." as documented,
and use a GtkApplicationWindow instead of a plain GtkWindow.
2011-12-08 21:53:03 +01:00
75e9fa9cfb test-gapplication: update for latest gapplication changes
g_application_set_action_group is deprecated, we should use
GActionMap. Also, GSimpleActions can now be constructed as normal
GObjects.
2011-12-02 22:15:14 +01:00
8997aa45b1 popupMenu: Remove app. from app actions 2011-12-01 12:33:07 -05:00
f884dbbfb2 Application Menu: add support for showing GApplication actions
Use the new GApplication support in ShellApp to create the application
menu. Supports plain (no state), boolean and double actions.
Includes a test application (as no other application uses GApplication
for actions)

https://bugzilla.gnome.org/show_bug.cgi?id=621203
2011-12-01 10:21:38 -05:00
d0c36bb732 ShellApp: port to new GDBusActionGroup and GMenuProxy API
GDBusActionGroup and GMenuProxy are new objects in GIO 2.32 that
help with accessing menus and actions of remote applications.
This patch makes it possible for the shell to associate an
application with a dbus name and from that a GMenu, that will
be shown as the application menu.

https://bugzilla.gnome.org/show_bug.cgi?id=621203
2011-11-25 18:20:38 -05:00
17c46c2452 Port everything to class framework
The last patch in the sequence. Every place that was previously
setting prototype has been ported to Lang.Class, to make code more
concise and allow for better toString().

https://bugzilla.gnome.org/show_bug.cgi?id=664436
2011-11-24 09:50:04 +01:00
0996174b3d Port GDM and Caribou to GDBus
During the mass port to GDBus, this classes were left out (probably
because they didn't exist at the time). Now it's time to update
them.

https://bugzilla.gnome.org/show_bug.cgi?id=664436
2011-11-24 09:50:04 +01:00
d6b6f814d3 Port all classes with inheritance to class framework
All classes that have at least one other derived class (and thus
benefit from the framework) have been now ported. These includes
NMDevice, SearchProvider, AltTab.SwitcherList, and some other
stuff around.

https://bugzilla.gnome.org/show_bug.cgi?id=664436
2011-11-24 09:50:04 +01:00
987099ea55 Port ModalDialog to the class framework
Similar to the previous commits, time to port shell modal dialogs
to the class framework.

https://bugzilla.gnome.org/show_bug.cgi?id=664436
2011-11-24 09:50:04 +01:00
b356aa8e3b Port message tray sources and notifications to class framework
Third step in the class framework port, now it's the turn of
MessageTray.Source and MessageTray.Notification, as well as
the various implementations around the shell.

https://bugzilla.gnome.org/show_bug.cgi?id=664436
2011-11-24 09:50:04 +01:00
566bdb50c2 Port PanelMenu to new class framework
Second patch in the class framework, now it's the turn of
PanelMenu (buttons, menus and status indicators).

https://bugzilla.gnome.org/show_bug.cgi?id=664436
2011-11-24 09:50:04 +01:00
2b57603271 Port PopupMenu to new Lang.Class framework
The Lang module in gjs has recently gained a small yet powerful
Class framework, that should help improve the readability of code
when using complex inheritance.
This commit starts porting shell code, by rewriting all classes in
popupMenu.js (and all derived classes) to Lang.Class.

https://bugzilla.gnome.org/show_bug.cgi?id=664436
2011-11-24 09:50:04 +01:00
c3528f5b6b lookingGlass: Fix global key press handler
No idea why connecting a key-press-event to a non-reactive actor
used to work, but some Clutter update broke it. Obvious fix is
to make the actor reactive.

https://bugzilla.gnome.org/show_bug.cgi?id=664582
2011-11-22 22:33:05 +01:00
76 changed files with 2674 additions and 1527 deletions

View File

@ -21,11 +21,9 @@
const Lang = imports.lang;
const Signals = imports.signals;
function Task() {
this._init.apply(this, arguments);
}
const Task = new Lang.Class({
Name: 'Task',
Task.prototype = {
_init: function(scope, handler) {
if (scope)
this.scope = scope;
@ -41,22 +39,17 @@ Task.prototype = {
return null;
},
};
});
Signals.addSignalMethods(Task.prototype);
function Hold() {
this._init.apply(this, arguments);
}
Hold.prototype = {
__proto__: Task.prototype,
const Hold = new Lang.Class({
Name: 'Hold',
Extends: Task,
_init: function() {
Task.prototype._init.call(this,
this,
function () {
return this;
});
this.parent(this, function () {
return this;
});
this._acquisitions = 1;
},
@ -88,18 +81,15 @@ Hold.prototype = {
isAcquired: function() {
return this._acquisitions > 0;
}
}
});
Signals.addSignalMethods(Hold.prototype);
function Batch() {
this._init.apply(this, arguments);
}
Batch.prototype = {
__proto__: Task.prototype,
const Batch = new Lang.Class({
Name: 'Batch',
Extends: Task,
_init: function(scope, tasks) {
Task.prototype._init.call(this);
this.parent();
this.tasks = [];
@ -166,20 +156,12 @@ Batch.prototype = {
cancel: function() {
this.tasks = this.tasks.splice(0, this._currentTaskIndex + 1);
}
};
});
Signals.addSignalMethods(Batch.prototype);
function ConcurrentBatch() {
this._init.apply(this, arguments);
}
ConcurrentBatch.prototype = {
__proto__: Batch.prototype,
_init: function(scope, tasks) {
Batch.prototype._init.call(this, scope, tasks);
},
const ConcurrentBatch = new Lang.Class({
Name: 'ConcurrentBatch',
Extends: Batch,
process: function() {
let hold = this.runTask();
@ -193,19 +175,12 @@ ConcurrentBatch.prototype = {
// concurrently.
this.nextTask();
}
};
});
Signals.addSignalMethods(ConcurrentBatch.prototype);
function ConsecutiveBatch() {
this._init.apply(this, arguments);
}
ConsecutiveBatch.prototype = {
__proto__: Batch.prototype,
_init: function(scope, tasks) {
Batch.prototype._init.call(this, scope, tasks);
},
const ConsecutiveBatch = new Lang.Class({
Name: 'ConsecutiveBatch',
Extends: Batch,
process: function() {
let hold = this.runTask();
@ -224,5 +199,5 @@ ConsecutiveBatch.prototype = {
this.nextTask();
}
}
};
});
Signals.addSignalMethods(ConsecutiveBatch.prototype);

View File

@ -1,32 +1,22 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DBus = imports.dbus;
const Gio = imports.gi.Gio;
const ConsoleKitManagerIface = {
name: 'org.freedesktop.ConsoleKit.Manager',
methods: [{ name: 'CanRestart',
inSignature: '',
outSignature: 'b' },
{ name: 'CanStop',
inSignature: '',
outSignature: 'b' },
{ name: 'Restart',
inSignature: '',
outSignature: '' },
{ name: 'Stop',
inSignature: '',
outSignature: '' }]
};
const ConsoleKitManagerIface = <interface name='org.freedesktop.ConsoleKit.Manager'>
<method name='CanRestart'>
<arg type='b' direction='out'/>
</method>
<method name='CanStop'>
<arg type='b' direction='out'/>
</method>
<method name='Restart' />
<method name='Stop' />
</interface>;
const ConsoleKitProxy = Gio.DBusProxy.makeProxyWrapper(ConsoleKitManagerIface);
function ConsoleKitManager() {
this._init();
return new ConsoleKitProxy(Gio.DBus.system,
'org.freedesktop.ConsoleKit',
'/org/freedesktop/ConsoleKit/Manager');
};
ConsoleKitManager.prototype = {
_init: function() {
DBus.system.proxifyObject(this,
'org.freedesktop.ConsoleKit',
'/org/freedesktop/ConsoleKit/Manager');
}
};
DBus.proxifyPrototype(ConsoleKitManager.prototype, ConsoleKitManagerIface);

View File

@ -1,26 +1,20 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DBus = imports.dbus;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const FprintManagerIface = {
name: 'net.reactivated.Fprint.Manager',
methods: [{ name: 'GetDefaultDevice',
inSignature: '',
outSignature: 'o' }]
};
const FprintManagerIface = <interface name='net.reactivated.Fprint.Manager'>
<method name='GetDefaultDevice'>
<arg type='o' direction='out' />
</method>
</interface>;
const FprintManagerProxy = Gio.DBusProxy.makeProxyWrapper(FprintManagerIface);
function FprintManager() {
this._init();
return new FprintManagerProxy(Gio.DBus.system,
'net.reactivated.Fprint',
'/net/reactivated/Fprint/Manager');
};
FprintManager.prototype = {
_init: function() {
DBus.system.proxifyObject(this,
'net.reactivated.Fprint',
'/net/reactivated/Fprint/Manager');
}
};
DBus.proxifyPrototype(FprintManager.prototype, FprintManagerIface);

View File

@ -33,7 +33,6 @@ const St = imports.gi.St;
const GdmGreeter = imports.gi.GdmGreeter;
const Batch = imports.gdm.batch;
const DBus = imports.dbus;
const Fprint = imports.gdm.fingerprint;
const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main;
@ -141,11 +140,9 @@ function _smoothlyResizeActor(actor, width, height) {
return hold;
}
function UserListItem(user, reason) {
this._init(user, reason);
}
const UserListItem = new Lang.Class({
Name: 'UserListItem',
UserListItem.prototype = {
_init: function(user) {
this.user = user;
this._userChangedId = this.user.connect('changed',
@ -274,15 +271,12 @@ UserListItem.prototype = {
});
return hold;
}
};
});
Signals.addSignalMethods(UserListItem.prototype);
function UserList() {
this._init.apply(this, arguments);
}
const UserList = new Lang.Class({
Name: 'UserList',
UserList.prototype = {
_init: function() {
this.actor = new St.ScrollView({ style_class: 'login-dialog-user-list-view'});
this.actor.set_policy(Gtk.PolicyType.NEVER,
@ -538,14 +532,12 @@ UserList.prototype = {
item.actor.destroy();
delete this._items[userName];
}
};
});
Signals.addSignalMethods(UserList.prototype);
function SessionListItem(id, name) {
this._init(id, name);
}
const SessionListItem = new Lang.Class({
Name: 'SessionListItem',
SessionListItem.prototype = {
_init: function(id, name) {
this.id = id;
@ -600,14 +592,12 @@ SessionListItem.prototype = {
_onClicked: function() {
this.emit('activate');
}
};
});
Signals.addSignalMethods(SessionListItem.prototype);
function SessionList() {
this._init();
}
const SessionList = new Lang.Class({
Name: 'SessionList',
SessionList.prototype = {
_init: function() {
this.actor = new St.Bin();
@ -738,24 +728,15 @@ SessionList.prototype = {
}));
}
}
};
});
Signals.addSignalMethods(SessionList.prototype);
function LoginDialog() {
if (_loginDialog == null) {
this._init();
_loginDialog = this;
}
return _loginDialog;
}
LoginDialog.prototype = {
__proto__: ModalDialog.ModalDialog.prototype,
const LoginDialog = new Lang.Class({
Name: 'LoginDialog',
Extends: ModalDialog.ModalDialog,
_init: function() {
ModalDialog.ModalDialog.prototype._init.call(this, { shellReactive: true,
styleClass: 'login-dialog' });
this.parent({ shellReactive: true, styleClass: 'login-dialog' });
this.connect('destroy',
Lang.bind(this, this._onDestroy));
this.connect('opened',
@ -908,7 +889,7 @@ LoginDialog.prototype = {
if (!this._settings.get_boolean(_FINGERPRINT_AUTHENTICATION_KEY))
return;
this._fprintManager.GetDefaultDeviceRemote(DBus.CALL_FLAG_START, Lang.bind(this,
this._fprintManager.GetDefaultDeviceRemote(Gio.DBusCallFlags.NONE, Lang.bind(this,
function(device, error) {
if (!error && device)
this._haveFingerprintReader = true;
@ -1399,8 +1380,8 @@ LoginDialog.prototype = {
},
close: function() {
ModalDialog.ModalDialog.prototype.close.call(this);
this.parent();
Main.ctrlAltTabManager.removeGroup(this._group);
}
};
});

View File

@ -25,15 +25,12 @@ const ConsoleKit = imports.gdm.consoleKit;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
function PowerMenuButton() {
this._init();
}
PowerMenuButton.prototype = {
__proto__: PanelMenu.SystemStatusButton.prototype,
const PowerMenuButton = new Lang.Class({
Name: 'PowerMenuButton',
Extends: PanelMenu.SystemStatusButton,
_init: function() {
PanelMenu.SystemStatusButton.prototype._init.call(this, 'system-shutdown', null);
this.parent('system-shutdown', null);
this._consoleKitManager = new ConsoleKit.ConsoleKitManager();
this._upClient = new UPowerGlib.Client();
@ -143,4 +140,4 @@ PowerMenuButton.prototype = {
if (this._haveShutdown)
this._consoleKitManager.StopRemote();
}
};
});

View File

@ -8,11 +8,9 @@ const Search = imports.ui.search;
const THUMBNAIL_ICON_MARGIN = 2;
function DocInfo(recentInfo) {
this._init(recentInfo);
}
const DocInfo = new Lang.Class({
Name: 'DocInfo',
DocInfo.prototype = {
_init : function(recentInfo) {
this.recentInfo = recentInfo;
// We actually used get_modified() instead of get_visited()
@ -49,7 +47,7 @@ DocInfo.prototype = {
}
return mtype;
}
};
});
var docManagerInstance = null;
@ -62,11 +60,9 @@ function getDocManager() {
/**
* DocManager wraps the DocSystem, primarily to expose DocInfo objects.
*/
function DocManager() {
this._init();
}
const DocManager = new Lang.Class({
Name: 'DocManager',
DocManager.prototype = {
_init: function() {
this._docSystem = Shell.DocSystem.get_default();
this._infosByTimestamp = [];
@ -135,6 +131,6 @@ DocManager.prototype = {
return this._infosByUri[url];
})), terms);
}
};
});
Signals.addSignalMethods(DocManager.prototype);

View File

@ -7,11 +7,9 @@ const Params = imports.misc.params;
const DEFAULT_LIMIT = 512;
function HistoryManager(params) {
this._init(params);
}
const HistoryManager = new Lang.Class({
Name: 'HistoryManager',
HistoryManager.prototype = {
_init: function(params) {
params = Params.parse(params, { gsettingsKey: null,
limit: DEFAULT_LIMIT,
@ -111,5 +109,5 @@ HistoryManager.prototype = {
if (this._key)
global.settings.set_strv(this._key, this._history);
}
};
});
Signals.addSignalMethods(HistoryManager.prototype);

View File

@ -54,11 +54,9 @@ function _getProvidersTable() {
return _providersTable = providers;
}
function ModemGsm() {
this._init.apply(this, arguments);
}
const ModemGsm = new Lang.Class({
Name: 'ModemGsm',
ModemGsm.prototype = {
_init: function(path) {
this._proxy = new ModemGsmNetworkProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
@ -156,14 +154,12 @@ ModemGsm.prototype = {
return name3 || name2 || null;
}
}
});
Signals.addSignalMethods(ModemGsm.prototype);
function ModemCdma() {
this._init.apply(this, arguments);
}
const ModemCdma = new Lang.Class({
Name: 'ModemCdma',
ModemCdma.prototype = {
_init: function(path) {
this._proxy = new ModemCdmaProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
@ -231,5 +227,5 @@ ModemCdma.prototype = {
return null;
}
};
});
Signals.addSignalMethods(ModemCdma.prototype);

View File

@ -43,11 +43,9 @@ function primaryModifier(mask) {
return primary;
}
function AltTabPopup() {
this._init();
}
const AltTabPopup = new Lang.Class({
Name: 'AltTabPopup',
AltTabPopup.prototype = {
_init : function() {
this.actor = new Shell.GenericContainer({ name: 'altTabPopup',
reactive: true,
@ -540,13 +538,11 @@ AltTabPopup.prototype = {
onComplete: Lang.bind(this, function () { this.thumbnailsVisible = true; })
});
}
};
});
function SwitcherList(squareItems) {
this._init(squareItems);
}
const SwitcherList = new Lang.Class({
Name: 'SwitcherList',
SwitcherList.prototype = {
_init : function(squareItems) {
this.actor = new Shell.GenericContainer({ style_class: 'switcher-list' });
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
@ -851,15 +847,13 @@ SwitcherList.prototype = {
// Clip the area for scrolling
this._clipBin.set_clip(0, -topPadding, (this.actor.allocation.x2 - this.actor.allocation.x1) - leftPadding - rightPadding, this.actor.height + bottomPadding);
}
};
});
Signals.addSignalMethods(SwitcherList.prototype);
function AppIcon(app) {
this._init(app);
}
const AppIcon = new Lang.Class({
Name: 'AppIcon',
AppIcon.prototype = {
_init: function(app) {
this.app = app;
this.actor = new St.BoxLayout({ style_class: 'alt-tab-app',
@ -877,17 +871,14 @@ AppIcon.prototype = {
this._iconBin.set_size(size, size);
this._iconBin.child = this.icon;
}
};
});
function AppSwitcher() {
this._init.apply(this, arguments);
}
AppSwitcher.prototype = {
__proto__ : SwitcherList.prototype,
const AppSwitcher = new Lang.Class({
Name: 'AppSwitcher',
Extends: SwitcherList,
_init : function(localApps, otherApps, altTabPopup) {
SwitcherList.prototype._init.call(this, true);
this.parent(true);
// Construct the AppIcons, add to the popup
let activeWorkspace = global.screen.get_active_workspace();
@ -966,7 +957,7 @@ AppSwitcher.prototype = {
_allocate: function (actor, box, flags) {
// Allocate the main list items
SwitcherList.prototype._allocate.call(this, actor, box, flags);
this.parent(actor, box, flags);
let arrowHeight = Math.floor(this.actor.get_theme_node().get_padding(St.Side.BOTTOM) / 3);
let arrowWidth = arrowHeight * 2;
@ -1021,7 +1012,7 @@ AppSwitcher.prototype = {
this._arrows[this._curApp].remove_style_pseudo_class('highlighted');
}
SwitcherList.prototype.highlight.call(this, n, justOutline);
this.parent(n, justOutline);
this._curApp = n;
if (this._curApp != -1) {
@ -1045,17 +1036,14 @@ AppSwitcher.prototype = {
if (appIcon.cachedWindows.length == 1)
arrow.hide();
}
};
});
function ThumbnailList(windows) {
this._init(windows);
}
ThumbnailList.prototype = {
__proto__ : SwitcherList.prototype,
const ThumbnailList = new Lang.Class({
Name: 'ThumbnailList',
Extends: SwitcherList,
_init : function(windows) {
SwitcherList.prototype._init.call(this);
this.parent(false);
let activeWorkspace = global.screen.get_active_workspace();
@ -1133,7 +1121,7 @@ ThumbnailList.prototype = {
// Make sure we only do this once
this._thumbnailBins = new Array();
}
};
});
function _drawArrow(area, side) {
let themeNode = area.get_theme_node();

View File

@ -26,11 +26,9 @@ const MAX_APPLICATION_WORK_MILLIS = 75;
const MENU_POPUP_TIMEOUT = 600;
const SCROLL_TIME = 0.1;
function AlphabeticalView() {
this._init();
}
const AlphabeticalView = new Lang.Class({
Name: 'AlphabeticalView',
AlphabeticalView.prototype = {
_init: function() {
this._grid = new IconGrid.IconGrid({ xAlign: St.Align.START });
this._appSystem = Shell.AppSystem.get_default();
@ -130,13 +128,11 @@ AlphabeticalView.prototype = {
this._addApp(app);
}
}
};
});
function ViewByCategories() {
this._init();
}
const ViewByCategories = new Lang.Class({
Name: 'ViewByCategories',
ViewByCategories.prototype = {
_init: function() {
this._appSystem = Shell.AppSystem.get_default();
this.actor = new St.BoxLayout({ style_class: 'all-app' });
@ -281,16 +277,14 @@ ViewByCategories.prototype = {
this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
}
}
};
});
/* This class represents a display containing a collection of application items.
* The applications are sorted based on their name.
*/
function AllAppDisplay() {
this._init();
}
const AllAppDisplay = new Lang.Class({
Name: 'AllAppDisplay',
AllAppDisplay.prototype = {
_init: function() {
this._appSystem = Shell.AppSystem.get_default();
this._appSystem.connect('installed-changed', Lang.bind(this, function() {
@ -306,17 +300,15 @@ AllAppDisplay.prototype = {
_redisplay: function() {
this._appView.refresh();
}
};
});
function AppSearchProvider() {
this._init();
}
AppSearchProvider.prototype = {
__proto__: Search.SearchProvider.prototype,
const AppSearchProvider = new Lang.Class({
Name: 'AppSearchProvider',
Extends: Search.SearchProvider,
_init: function() {
Search.SearchProvider.prototype._init.call(this, _("APPLICATIONS"));
this.parent(_("APPLICATIONS"));
this._appSys = Shell.AppSystem.get_default();
},
@ -364,17 +356,15 @@ AppSearchProvider.prototype = {
let icon = new AppWellIcon(app);
return icon.actor;
}
};
});
function SettingsSearchProvider() {
this._init();
}
SettingsSearchProvider.prototype = {
__proto__: Search.SearchProvider.prototype,
const SettingsSearchProvider = new Lang.Class({
Name: 'SettingsSearchProvider',
Extends: Search.SearchProvider,
_init: function() {
Search.SearchProvider.prototype._init.call(this, _("SETTINGS"));
this.parent(_("SETTINGS"));
this._appSys = Shell.AppSystem.get_default();
this._gnomecc = this._appSys.lookup_app('gnome-control-center.desktop');
},
@ -412,35 +402,28 @@ SettingsSearchProvider.prototype = {
let icon = new AppWellIcon(app);
return icon.actor;
}
};
});
function AppIcon(app, params) {
this._init(app, params);
}
AppIcon.prototype = {
__proto__: IconGrid.BaseIcon.prototype,
const AppIcon = new Lang.Class({
Name: 'AppIcon',
Extends: IconGrid.BaseIcon,
_init : function(app, params) {
this.app = app;
let label = this.app.get_name();
IconGrid.BaseIcon.prototype._init.call(this,
label,
params);
this.parent(label, params);
},
createIcon: function(iconSize) {
return this.app.create_icon_texture(iconSize);
}
};
});
function AppWellIcon(app, iconParams, onActivateOverride) {
this._init(app, iconParams, onActivateOverride);
}
const AppWellIcon = new Lang.Class({
Name: 'AppWellIcon',
AppWellIcon.prototype = {
_init : function(app, iconParams, onActivateOverride) {
this.app = app;
this.actor = new St.Button({ style_class: 'app-well-app',
@ -620,22 +603,19 @@ AppWellIcon.prototype = {
getDragActorSource: function() {
return this.icon.icon;
}
};
});
Signals.addSignalMethods(AppWellIcon.prototype);
function AppIconMenu(source) {
this._init(source);
}
AppIconMenu.prototype = {
__proto__: PopupMenu.PopupMenu.prototype,
const AppIconMenu = new Lang.Class({
Name: 'AppIconMenu',
Extends: PopupMenu.PopupMenu,
_init: function(source) {
let side = St.Side.LEFT;
if (St.Widget.get_default_direction() == St.TextDirection.RTL)
side = St.Side.RIGHT;
PopupMenu.PopupMenu.prototype._init.call(this, source.actor, 0.5, side);
this.parent(source.actor, 0.5, side);
// We want to keep the item hovered while the menu is up
this.blockSourceEvents = true;
@ -723,5 +703,5 @@ AppIconMenu.prototype = {
}
this.close();
}
};
});
Signals.addSignalMethods(AppIconMenu.prototype);

View File

@ -6,11 +6,9 @@ const Signals = imports.signals;
const Main = imports.ui.main;
function AppFavorites() {
this._init();
}
const AppFavorites = new Lang.Class({
Name: 'AppFavorites',
AppFavorites.prototype = {
FAVORITE_APPS_KEY: 'favorite-apps',
_init: function() {
@ -122,7 +120,7 @@ AppFavorites.prototype = {
this._addFavorite(appId, pos);
}));
}
};
});
Signals.addSignalMethods(AppFavorites.prototype);
var appFavoritesInstance = null;

View File

@ -64,11 +64,9 @@ function ConsoleKitManager() {
return self;
}
function AutomountManager() {
this._init();
}
const AutomountManager = new Lang.Class({
Name: 'AutomountManager',
AutomountManager.prototype = {
_init: function() {
this._settings = new Gio.Settings({ schema: SETTINGS_SCHEMA });
this._volumeQueue = [];
@ -268,4 +266,4 @@ AutomountManager.prototype = {
return false;
});
}
}
});

View File

@ -75,11 +75,9 @@ function HotplugSniffer() {
'/org/gnome/Shell/HotplugSniffer');
}
function ContentTypeDiscoverer(callback) {
this._init(callback);
}
const ContentTypeDiscoverer = new Lang.Class({
Name: 'ContentTypeDiscoverer',
ContentTypeDiscoverer.prototype = {
_init: function(callback) {
this._callback = callback;
},
@ -136,13 +134,11 @@ ContentTypeDiscoverer.prototype = {
this._callback(mount, apps, contentTypes);
}
}
});
function AutorunManager() {
this._init();
}
const AutorunManager = new Lang.Class({
Name: 'AutorunManager',
AutorunManager.prototype = {
_init: function() {
this._volumeMonitor = Gio.VolumeMonitor.get();
@ -259,17 +255,14 @@ AutorunManager.prototype = {
+ ': ' + e.toString());
}
},
}
});
function AutorunResidentSource() {
this._init();
}
AutorunResidentSource.prototype = {
__proto__: MessageTray.Source.prototype,
const AutorunResidentSource = new Lang.Class({
Name: 'AutorunResidentSource',
Extends: MessageTray.Source,
_init: function() {
MessageTray.Source.prototype._init.call(this, _("Removable Devices"));
this.parent(_("Removable Devices"));
this._mounts = [];
@ -324,19 +317,14 @@ AutorunResidentSource.prototype = {
icon_type: St.IconType.FULLCOLOR,
icon_size: this.ICON_SIZE });
}
}
});
function AutorunResidentNotification(source) {
this._init(source);
}
AutorunResidentNotification.prototype = {
__proto__: MessageTray.Notification.prototype,
const AutorunResidentNotification = new Lang.Class({
Name: 'AutorunResidentNotification',
Extends: MessageTray.Notification,
_init: function(source) {
MessageTray.Notification.prototype._init.call(this, source,
source.title, null,
{ customContent: true });
this.parent(source, source.title, null, { customContent: true });
// set the notification as resident
this.setResident(true);
@ -410,13 +398,11 @@ AutorunResidentNotification.prototype = {
return item;
},
}
});
function AutorunTransientDispatcher() {
this._init();
}
const AutorunTransientDispatcher = new Lang.Class({
Name: 'AutorunTransientDispatcher',
AutorunTransientDispatcher.prototype = {
_init: function() {
this._sources = [];
this._settings = new Gio.Settings({ schema: SETTINGS_SCHEMA });
@ -507,17 +493,14 @@ AutorunTransientDispatcher.prototype = {
// destroy the notification source
source.destroy();
}
}
});
function AutorunTransientSource(mount, apps) {
this._init(mount, apps);
}
AutorunTransientSource.prototype = {
__proto__: MessageTray.Source.prototype,
const AutorunTransientSource = new Lang.Class({
Name: 'AutorunTransientSource',
Extends: MessageTray.Source,
_init: function(mount, apps) {
MessageTray.Source.prototype._init.call(this, mount.get_name());
this.parent(mount.get_name());
this.mount = mount;
this.apps = apps;
@ -534,19 +517,14 @@ AutorunTransientSource.prototype = {
return new St.Icon({ gicon: this.mount.get_icon(),
icon_size: this.ICON_SIZE });
}
}
});
function AutorunTransientNotification(source) {
this._init(source);
}
AutorunTransientNotification.prototype = {
__proto__: MessageTray.Notification.prototype,
const AutorunTransientNotification = new Lang.Class({
Name: 'AutorunTransientNotification',
Extends: MessageTray.Notification,
_init: function(source) {
MessageTray.Notification.prototype._init.call(this, source,
source.title, null,
{ customContent: true });
this.parent(source, source.title, null, { customContent: true });
this._box = new St.BoxLayout({ style_class: 'hotplug-transient-box',
vertical: true });
@ -621,5 +599,5 @@ AutorunTransientNotification.prototype = {
return button;
}
}
});

View File

@ -21,11 +21,9 @@ const POPUP_ANIMATION_TIME = 0.15;
* placed. The arrow position may be controlled via setArrowOrigin().
*
*/
function BoxPointer(side, binProperties) {
this._init(side, binProperties);
}
const BoxPointer = new Lang.Class({
Name: 'BoxPointer',
BoxPointer.prototype = {
_init: function(arrowSide, binProperties) {
this._arrowSide = arrowSide;
this._arrowOrigin = 0;
@ -452,4 +450,4 @@ BoxPointer.prototype = {
get opacity() {
return this.actor.opacity;
}
};
});

View File

@ -155,28 +155,24 @@ function _getEventDayAbbreviation(dayNumber) {
// Abstraction for an appointment/event in a calendar
function CalendarEvent(date, end, summary, allDay) {
this._init(date, end, summary, allDay);
}
const CalendarEvent = new Lang.Class({
Name: 'CalendarEvent',
CalendarEvent.prototype = {
_init: function(date, end, summary, allDay) {
this.date = date;
this.end = end;
this.summary = summary;
this.allDay = allDay;
}
};
});
// Interface for appointments/events - e.g. the contents of a calendar
//
// First, an implementation with no events
function EmptyEventSource() {
this._init();
}
const EmptyEventSource = new Lang.Class({
Name: 'EmptyEventSource',
EmptyEventSource.prototype = {
_init: function() {
},
@ -191,7 +187,7 @@ EmptyEventSource.prototype = {
hasEvents: function(day) {
return false;
}
};
});
Signals.addSignalMethods(EmptyEventSource.prototype);
const CalendarServerIface = <interface name="org.gnome.Shell.CalendarServer">
@ -219,11 +215,6 @@ function CalendarServer() {
return self;
}
// an implementation that reads data from a session bus service
function DBusEventSource() {
this._init();
}
function _datesEqual(a, b) {
if (a < b)
return false;
@ -242,8 +233,10 @@ function _dateIntervalsOverlap(a0, a1, b0, b1)
return true;
}
// an implementation that reads data from a session bus service
const DBusEventSource = new Lang.Class({
Name: 'DBusEventSource',
DBusEventSource.prototype = {
_init: function() {
this._resetCache();
@ -344,17 +337,15 @@ DBusEventSource.prototype = {
return true;
}
};
});
Signals.addSignalMethods(DBusEventSource.prototype);
// Calendar:
// @eventSource: is an object implementing the EventSource API, e.g. the
// requestRange(), getEvents(), hasEvents() methods and the ::changed signal.
function Calendar(eventSource) {
this._init(eventSource);
}
const Calendar = new Lang.Class({
Name: 'Calendar',
Calendar.prototype = {
_init: function(eventSource) {
if (eventSource) {
this._eventSource = eventSource;
@ -620,15 +611,13 @@ Calendar.prototype = {
if (this._eventSource)
this._eventSource.requestRange(beginDate, iter, forceReload);
}
};
});
Signals.addSignalMethods(Calendar.prototype);
function EventsList(eventSource) {
this._init(eventSource);
}
const EventsList = new Lang.Class({
Name: 'EventsList',
EventsList.prototype = {
_init: function(eventSource) {
this.actor = new St.BoxLayout({ vertical: true, style_class: 'events-header-vbox'});
this._date = new Date();
@ -759,4 +748,4 @@ EventsList.prototype = {
this._showOtherDay(this._date);
}
}
};
});

View File

@ -20,11 +20,9 @@ function launchContact(id) {
/* This class represents a shown contact search result in the overview */
function Contact(id) {
this._init(id);
}
const Contact = new Lang.Class({
Name: 'Contact',
Contact.prototype = {
_init: function(id) {
this._contactSys = Shell.ContactSystem.get_default();
this.individual = this._contactSys.get_individual(id);
@ -131,19 +129,16 @@ Contact.prototype = {
return tc.load_icon_name(null, 'avatar-default', St.IconType.FULLCOLOR, size);
}
},
};
});
/* Searches for and returns contacts */
function ContactSearchProvider() {
this._init();
}
ContactSearchProvider.prototype = {
__proto__: Search.SearchProvider.prototype,
const ContactSearchProvider = new Lang.Class({
Name: 'ContactSearchProvider',
Extends: Search.SearchProvider,
_init: function() {
Search.SearchProvider.prototype._init.call(this, _("CONTACTS"));
this.parent(_("CONTACTS"));
this._contactSys = Shell.ContactSystem.get_default();
},
@ -182,4 +177,4 @@ ContactSearchProvider.prototype = {
activateResult: function(id, params) {
launchContact(id);
}
};
});

View File

@ -22,11 +22,9 @@ const SortGroup = {
BOTTOM: 2
};
function CtrlAltTabManager() {
this._init();
}
const CtrlAltTabManager = new Lang.Class({
Name: 'CtrlAltTabManager',
CtrlAltTabManager.prototype = {
_init: function() {
this._items = [];
this._focusManager = St.FocusManager.get_for_stage(global.stage);
@ -134,17 +132,15 @@ CtrlAltTabManager.prototype = {
}));
}
}
};
});
function mod(a, b) {
return (a + b) % b;
}
function CtrlAltTabPopup() {
this._init();
}
const CtrlAltTabPopup = new Lang.Class({
Name: 'CtrlAltTabPopup',
CtrlAltTabPopup.prototype = {
_init : function() {
this.actor = new Shell.GenericContainer({ name: 'ctrlAltTabPopup',
reactive: true });
@ -303,17 +299,14 @@ CtrlAltTabPopup.prototype = {
this._selection = num;
this._switcher.highlight(num);
}
};
});
function CtrlAltTabSwitcher(items) {
this._init(items);
}
CtrlAltTabSwitcher.prototype = {
__proto__ : AltTab.SwitcherList.prototype,
const CtrlAltTabSwitcher = new Lang.Class({
Name: 'CtrlAltTabSwitcher',
Extends: AltTab.SwitcherList,
_init : function(items) {
AltTab.SwitcherList.prototype._init.call(this, true);
this.parent(true);
for (let i = 0; i < items.length; i++)
this._addIcon(items[i]);
@ -336,4 +329,4 @@ CtrlAltTabSwitcher.prototype = {
this.addItem(box, text);
}
};
});

View File

@ -19,11 +19,9 @@ const DASH_ANIMATION_TIME = 0.2;
// A container like StBin, but taking the child's scale into account
// when requesting a size
function DashItemContainer() {
this._init();
}
const DashItemContainer = new Lang.Class({
Name: 'DashItemContainer',
DashItemContainer.prototype = {
_init: function() {
this.actor = new Shell.GenericContainer({ style_class: 'dash-item-container' });
this.actor.connect('get-preferred-width',
@ -157,17 +155,14 @@ DashItemContainer.prototype = {
get childOpacity() {
return this._childOpacity;
}
};
});
function RemoveFavoriteIcon() {
this._init();
}
RemoveFavoriteIcon.prototype = {
__proto__: DashItemContainer.prototype,
const RemoveFavoriteIcon = new Lang.Class({
Name: 'RemoveFavoriteIcon',
Extends: DashItemContainer,
_init: function() {
DashItemContainer.prototype._init.call(this);
this.parent();
this._iconBin = new St.Bin({ style_class: 'remove-favorite' });
this._iconActor = null;
@ -219,28 +214,21 @@ RemoveFavoriteIcon.prototype = {
return true;
}
};
});
function DragPlaceholderItem() {
this._init();
}
DragPlaceholderItem.prototype = {
__proto__: DashItemContainer.prototype,
const DragPlaceholderItem = new Lang.Class({
Name: 'DragPlaceholderItem',
Extends: DashItemContainer,
_init: function() {
DashItemContainer.prototype._init.call(this);
this.parent();
this.setChild(new St.Bin({ style_class: 'placeholder' }));
}
};
});
const Dash = new Lang.Class({
Name: 'Dash',
function Dash() {
this._init();
}
Dash.prototype = {
_init : function() {
this._maxHeight = -1;
this.iconSize = 64;
@ -762,6 +750,6 @@ Dash.prototype = {
return true;
}
};
});
Signals.addSignalMethods(Dash.prototype);

View File

@ -40,12 +40,9 @@ function _onVertSepRepaint (area)
cr.stroke();
};
function DateMenuButton() {
this._init.apply(this, arguments);
}
DateMenuButton.prototype = {
__proto__: PanelMenu.Button.prototype,
const DateMenuButton = new Lang.Class({
Name: 'DateMenuButton',
Extends: PanelMenu.Button,
_init: function(params) {
params = Params.parse(params, { showEvents: true });
@ -57,7 +54,7 @@ DateMenuButton.prototype = {
let menuAlignment = 0.25;
if (St.Widget.get_default_direction() == St.TextDirection.RTL)
menuAlignment = 1.0 - menuAlignment;
PanelMenu.Button.prototype._init.call(this, menuAlignment);
this.parent(menuAlignment);
this._clock = new St.Label();
this.actor.add_actor(this._clock);
@ -239,4 +236,4 @@ DateMenuButton.prototype = {
}
}
}
};
});

View File

@ -69,11 +69,9 @@ function removeDragMonitor(monitor) {
}
}
function _Draggable(actor, params) {
this._init(actor, params);
}
const _Draggable = new Lang.Class({
Name: 'Draggable',
_Draggable.prototype = {
_init : function(actor, params) {
params = Params.parse(params, { manualMode: false,
restoreOnSuccess: false,
@ -596,7 +594,7 @@ _Draggable.prototype = {
this._dragActor = undefined;
currentDraggable = null;
}
};
});
Signals.addSignalMethods(_Draggable.prototype);

View File

@ -1,19 +1,16 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DocInfo = imports.misc.docInfo;
const Lang = imports.lang;
const Params = imports.misc.params;
const Search = imports.ui.search;
function DocSearchProvider() {
this._init();
}
DocSearchProvider.prototype = {
__proto__: Search.SearchProvider.prototype,
const DocSearchProvider = new Lang.Class({
Name: 'DocSearchProvider',
Extends: Search.SearchProvider,
_init: function(name) {
Search.SearchProvider.prototype._init.call(this, _("RECENT ITEMS"));
this.parent(_("RECENT ITEMS"));
this._docManager = DocInfo.getDocManager();
},
@ -44,4 +41,4 @@ DocSearchProvider.prototype = {
getSubsearchResultSet: function(previousResults, terms) {
return this._docManager.subsearch(previousResults, terms);
}
};
});

View File

@ -142,11 +142,9 @@ function findAppFromInhibitor(inhibitor) {
return app;
}
function ListItem(app, reason) {
this._init(app, reason);
}
const ListItem = new Lang.Class({
Name: 'ListItem',
ListItem.prototype = {
_init: function(app, reason) {
this._app = app;
this._reason = reason;
@ -192,7 +190,7 @@ ListItem.prototype = {
this.emit('activate');
this._app.activate();
}
};
});
Signals.addSignalMethods(ListItem.prototype);
// The logout timer only shows updates every 10 seconds
@ -230,27 +228,19 @@ function _setLabelText(label, text) {
}
}
function EndSessionDialog() {
if (_endSessionDialog == null) {
this._init();
_endSessionDialog = this;
}
return _endSessionDialog;
}
function init() {
// This always returns the same singleton object
// By instantiating it initially, we register the
// bus object, etc.
let dialog = new EndSessionDialog();
_endSessionDialog = new EndSessionDialog();
}
EndSessionDialog.prototype = {
__proto__: ModalDialog.ModalDialog.prototype,
const EndSessionDialog = new Lang.Class({
Name: 'EndSessionDialog',
Extends: ModalDialog.ModalDialog,
_init: function() {
ModalDialog.ModalDialog.prototype._init.call(this, { styleClass: 'end-session-dialog' });
this.parent({ styleClass: 'end-session-dialog' });
this._user = AccountsService.UserManager.get_default().get_user(GLib.get_user_name());
@ -441,7 +431,7 @@ EndSessionDialog.prototype = {
},
close: function() {
ModalDialog.ModalDialog.prototype.close.call(this);
this.parent();
this._dbusImpl.emit_signal('Closed', null);
},
@ -543,4 +533,4 @@ EndSessionDialog.prototype = {
this.disconnect(signalId);
}));
}
};
});

View File

@ -502,15 +502,12 @@ function loadExtensions() {
_loadExtensionsIn(userExtensionsDir, ExtensionType.PER_USER);
}
function InstallExtensionDialog(uuid, version_tag, name) {
this._init(uuid, version_tag, name);
}
InstallExtensionDialog.prototype = {
__proto__: ModalDialog.ModalDialog.prototype,
const InstallExtensionDialog = new Lang.Class({
Name: 'InstallExtensionDialog',
Extends: ModalDialog.ModalDialog,
_init: function(uuid, version_tag, name) {
ModalDialog.ModalDialog.prototype._init.call(this, { styleClass: 'extension-dialog' });
this.parent({ styleClass: 'extension-dialog' });
this._uuid = uuid;
this._version_tag = version_tag;
@ -570,4 +567,4 @@ InstallExtensionDialog.prototype = {
this.close(global.get_current_time());
}
};
});

View File

@ -10,11 +10,9 @@ const Params = imports.misc.params;
const ICON_SIZE = 48;
function BaseIcon(label, createIcon) {
this._init(label, createIcon);
}
const BaseIcon = new Lang.Class({
Name: 'BaseIcon',
BaseIcon.prototype = {
_init : function(label, params) {
params = Params.parse(params, { createIcon: null,
setSizeManually: false,
@ -149,13 +147,11 @@ BaseIcon.prototype = {
this._createIconTexture(size);
}
};
});
function IconGrid(params) {
this._init(params);
}
const IconGrid = new Lang.Class({
Name: 'IconGrid',
IconGrid.prototype = {
_init: function(params) {
params = Params.parse(params, { rowLimit: null,
columnLimit: null,
@ -324,4 +320,4 @@ IconGrid.prototype = {
visibleItemsCount: function() {
return this._grid.get_children().length - this._grid.get_n_skip_paint();
}
};
});

View File

@ -39,34 +39,31 @@ const PRETTY_KEYS = {
'Alt_L': 'Alt'
};
const CaribouKeyboardIface = {
name: 'org.gnome.Caribou.Keyboard',
methods: [ { name: 'Show',
inSignature: 'u',
outSignature: ''
},
{ name: 'Hide',
inSignature: 'u',
outSignature: ''
},
{ name: 'SetCursorLocation',
inSignature: 'iiii',
outSignature: ''
},
{ name: 'SetEntryLocation',
inSignature: 'iiii',
outSignature: ''
} ],
properties: [ { name: 'Name',
signature: 's',
access: 'read' } ]
};
const CaribouKeyboardIface = <interface name='org.gnome.Caribou.Keyboard'>
<method name='Show'>
<arg type='u' direction='in' />
</method>
<method name='Hide'>
<arg type='u' direction='in' />
</method>
<method name='SetCursorLocation'>
<arg type='i' direction='in' />
<arg type='i' direction='in' />
<arg type='i' direction='in' />
<arg type='i' direction='in' />
</method>
<method name='SetEntryLocation'>
<arg type='i' direction='in' />
<arg type='i' direction='in' />
<arg type='i' direction='in' />
<arg type='i' direction='in' />
</method>
<property name='Name' access='read' type='s' />
</interface>;
function Key() {
this._init.apply(this, arguments);
}
const Key = new Lang.Class({
Name: 'Key',
Key.prototype = {
_init : function(key) {
this._key = key;
@ -192,15 +189,15 @@ Key.prototype = {
this._boxPointer.hide(true);
}
}
};
});
function Keyboard() {
this._init.apply(this, arguments);
}
const Keyboard = new Lang.Class({
// HACK: we can't set Name, because it collides with Name dbus property
// Name: 'Keyboard',
Keyboard.prototype = {
_init: function () {
DBus.session.exportObject('/org/gnome/Caribou/Keyboard', this);
this._impl = Gio.DBusExportedObject.wrapJSObject(CaribouKeyboardIface, this);
this._impl.export(Gio.DBus.session, '/org/gnome/Caribou/Keyboard');
this.actor = null;
@ -532,19 +529,15 @@ Keyboard.prototype = {
get Name() {
return 'gnome-shell';
}
};
DBus.conformExport(Keyboard.prototype, CaribouKeyboardIface);
});
function KeyboardSource() {
this._init.apply(this, arguments);
}
KeyboardSource.prototype = {
__proto__: MessageTray.Source.prototype,
const KeyboardSource = new Lang.Class({
Name: 'KeyboardSource',
Extends: MessageTray.Source,
_init: function(keyboard) {
this.parent(_("Keyboard"));
this._keyboard = keyboard;
MessageTray.Source.prototype._init.call(this, _("Keyboard"));
this._setSummaryIcon(this.createNotificationIcon());
},
@ -555,7 +548,7 @@ KeyboardSource.prototype = {
icon_size: this.ICON_SIZE });
},
handleSummaryClick: function() {
handleSummaryClick: function() {
let event = Clutter.get_current_event();
if (event.type() != Clutter.EventType.BUTTON_RELEASE)
return false;
@ -567,4 +560,4 @@ KeyboardSource.prototype = {
open: function() {
this._keyboard.show();
}
};
});

View File

@ -17,11 +17,9 @@ const HOT_CORNER_ACTIVATION_TIMEOUT = 0.5;
const STARTUP_ANIMATION_TIME = 0.2;
const KEYBOARD_ANIMATION_TIME = 0.5;
function LayoutManager() {
this._init.apply(this, arguments);
}
const LayoutManager = new Lang.Class({
Name: 'LayoutManager',
LayoutManager.prototype = {
_init: function () {
this._rtl = (St.Widget.get_default_direction() == St.TextDirection.RTL);
this.monitors = [];
@ -374,7 +372,7 @@ LayoutManager.prototype = {
findMonitorForActor: function(actor) {
return this._chrome.findMonitorForActor(actor);
}
};
});
Signals.addSignalMethods(LayoutManager.prototype);
@ -382,11 +380,9 @@ Signals.addSignalMethods(LayoutManager.prototype);
//
// This class manages a "hot corner" that can toggle switching to
// overview.
function HotCorner() {
this._init();
}
const HotCorner = new Lang.Class({
Name: 'HotCorner',
HotCorner.prototype = {
_init : function() {
// We use this flag to mark the case where the user has entered the
// hot corner and has not left both the hot corner and a surrounding
@ -548,7 +544,7 @@ HotCorner.prototype = {
return true;
return false;
}
};
});
// This manages the shell "chrome"; the UI that's visible in the
@ -561,11 +557,9 @@ const defaultParams = {
affectsInputRegion: true
};
function Chrome() {
this._init.apply(this, arguments);
}
const Chrome = new Lang.Class({
Name: 'Chrome',
Chrome.prototype = {
_init: function(layoutManager) {
this._layoutManager = layoutManager;
@ -981,4 +975,4 @@ Chrome.prototype = {
return false;
}
};
});

View File

@ -30,11 +30,9 @@ const Tweener = imports.ui.tweener;
* @container and will track any changes in its size. You can override
* this by passing an explicit width and height in @params.
*/
function Lightbox(container, params) {
this._init(container, params);
}
const Lightbox = new Lang.Class({
Name: 'Lightbox',
Lightbox.prototype = {
_init : function(container, params) {
params = Params.parse(params, { inhibitEvents: false,
width: null,
@ -196,4 +194,4 @@ Lightbox.prototype = {
this.highlight(null);
}
};
});

View File

@ -4,11 +4,9 @@ const Lang = imports.lang;
const Signals = imports.signals;
const St = imports.gi.St;
function Link(props) {
this._init(props);
}
const Link = new Lang.Class({
Name: 'Link',
Link.prototype = {
_init : function(props) {
let realProps = { reactive: true,
track_hover: true,
@ -19,6 +17,5 @@ Link.prototype = {
this.actor = new St.Button(realProps);
}
};
});
Signals.addSignalMethods(Link.prototype);

View File

@ -55,11 +55,9 @@ function _getAutoCompleteGlobalKeywords() {
return keywords.concat(windowProperties).concat(headerProperties);
}
function AutoComplete(entry) {
this._init(entry);
}
const AutoComplete = new Lang.Class({
Name: 'AutoComplete',
AutoComplete.prototype = {
_init: function(entry) {
this._entry = entry;
this._entry.connect('key-press-event', Lang.bind(this, this._entryKeyPressEvent));
@ -118,15 +116,13 @@ AutoComplete.prototype = {
this._entry.clutter_text.insert_text(additionalCompletionText, cursorPos);
}
};
});
Signals.addSignalMethods(AutoComplete.prototype);
function Notebook() {
this._init();
}
const Notebook = new Lang.Class({
Name: 'Notebook',
Notebook.prototype = {
_init: function() {
this.actor = new St.BoxLayout({ vertical: true });
@ -250,7 +246,7 @@ Notebook.prototype = {
this.selectIndex(prevIndex);
}
};
});
Signals.addSignalMethods(Notebook.prototype);
function objectToString(o) {
@ -262,12 +258,9 @@ function objectToString(o) {
}
}
function ObjLink(o, title) {
this._init(o, title);
}
ObjLink.prototype = {
__proto__: Link.Link,
const ObjLink = new Lang.Class({
Name: 'ObjLink',
Extends: Link.Link,
_init: function(o, title) {
let text;
@ -277,7 +270,8 @@ ObjLink.prototype = {
text = objectToString(o);
text = GLib.markup_escape_text(text, -1);
this._obj = o;
Link.Link.prototype._init.call(this, { label: text });
this.parent({ label: text });
this.actor.get_child().single_line_mode = true;
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
},
@ -285,13 +279,11 @@ ObjLink.prototype = {
_onClicked: function (link) {
Main.lookingGlass.inspectObject(this._obj, this.actor);
}
};
});
function Result(command, o, index) {
this._init(command, o, index);
}
const Result = new Lang.Class({
Name: 'Result',
Result.prototype = {
_init : function(command, o, index) {
this.index = index;
this.o = o;
@ -313,13 +305,11 @@ Result.prototype = {
padBin.add_actor(line);
this.actor.add(padBin);
}
};
});
function WindowList() {
this._init();
}
const WindowList = new Lang.Class({
Name: 'WindowList',
WindowList.prototype = {
_init : function () {
this.actor = new St.BoxLayout({ name: 'Windows', vertical: true, style: 'spacing: 8px' });
let tracker = Shell.WindowTracker.get_default();
@ -360,14 +350,12 @@ WindowList.prototype = {
}
}
}
};
});
Signals.addSignalMethods(WindowList.prototype);
function ObjInspector() {
this._init();
}
const ObjInspector = new Lang.Class({
Name: 'ObjInspector',
ObjInspector.prototype = {
_init : function () {
this._obj = null;
this._previousObj = null;
@ -467,7 +455,7 @@ ObjInspector.prototype = {
_onBack: function() {
this.selectObject(this._previousObj, true);
}
};
});
function addBorderPaintHook(actor) {
let signalId = actor.connect_after('paint',
@ -493,11 +481,9 @@ function addBorderPaintHook(actor) {
return signalId;
}
function Inspector() {
this._init();
}
const Inspector = new Lang.Class({
Name: 'Inspector',
Inspector.prototype = {
_init: function() {
let container = new Shell.GenericContainer({ width: 0,
height: 0 });
@ -636,15 +622,13 @@ Inspector.prototype = {
this._borderPaintId = addBorderPaintHook(this._target);
}
}
};
});
Signals.addSignalMethods(Inspector.prototype);
function ErrorLog() {
this._init();
}
const ErrorLog = new Lang.Class({
Name: 'ErrorLog',
ErrorLog.prototype = {
_init: function() {
this.actor = new St.BoxLayout();
this.text = new St.Label();
@ -679,13 +663,11 @@ ErrorLog.prototype = {
}
this.text.text = text;
}
};
});
function Memory() {
this._init();
}
const Memory = new Lang.Class({
Name: 'Memory',
Memory.prototype = {
_init: function() {
this.actor = new St.BoxLayout({ vertical: true });
this._glibc_uordblks = new St.Label();
@ -730,13 +712,11 @@ Memory.prototype = {
this._gjs_closure.text = 'gjs_closure: ' + memInfo.gjs_closure;
this._last_gc_seconds_ago.text = 'last_gc_seconds_ago: ' + memInfo.last_gc_seconds_ago;
}
};
});
function Extensions() {
this._init();
}
const Extensions = new Lang.Class({
Name: 'Extensions',
Extensions.prototype = {
_init: function() {
this.actor = new St.BoxLayout({ vertical: true,
name: 'lookingGlassExtensions' });
@ -866,13 +846,11 @@ Extensions.prototype = {
return box;
}
};
});
function LookingGlass() {
this._init();
}
const LookingGlass = new Lang.Class({
Name: 'LookingGlass',
LookingGlass.prototype = {
_init : function() {
this._borderPaintTarget = null;
this._borderPaintId = 0;
@ -889,7 +867,8 @@ LookingGlass.prototype = {
this.actor = new St.BoxLayout({ name: 'LookingGlassDialog',
style_class: 'lg-dialog',
vertical: true,
visible: false });
visible: false,
reactive: true });
this.actor.connect('key-press-event', Lang.bind(this, this._globalKeyPressEvent));
this._interfaceSettings = new Gio.Settings({ schema: 'org.gnome.desktop.interface' });
@ -1228,5 +1207,5 @@ LookingGlass.prototype = {
})
});
}
};
});
Signals.addSignalMethods(LookingGlass.prototype);

View File

@ -36,11 +36,9 @@ const CROSS_HAIRS_CLIP_KEY = 'cross-hairs-clip';
let magDBusService = null;
function Magnifier() {
this._init();
}
const Magnifier = new Lang.Class({
Name: 'Magnifier',
Magnifier.prototype = {
_init: function() {
// Magnifier is a manager of ZoomRegions.
this._zoomRegions = [];
@ -543,14 +541,12 @@ Magnifier.prototype = {
);
}
}
};
});
Signals.addSignalMethods(Magnifier.prototype);
function ZoomRegion(magnifier, mouseSourceActor) {
this._init(magnifier, mouseSourceActor);
}
const ZoomRegion = new Lang.Class({
Name: 'ZoomRegion',
ZoomRegion.prototype = {
_init: function(magnifier, mouseSourceActor) {
this._magnifier = magnifier;
@ -1150,13 +1146,11 @@ ZoomRegion.prototype = {
yMagMouse - groupHeight / 2);
}
}
};
});
function Crosshairs() {
this._init();
}
const Crosshairs = new Lang.Class({
Name: 'Crosshairs',
Crosshairs.prototype = {
_init: function() {
// Set the group containing the crosshairs to three times the desktop
@ -1412,4 +1406,4 @@ Crosshairs.prototype = {
this._vertTopHair.set_position((groupWidth - thickness) / 2, top);
this._vertBottomHair.set_position((groupWidth - thickness) / 2, bottom);
}
};
});

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Main = imports.ui.main;
const MAG_SERVICE_NAME = 'org.gnome.Magnifier';
@ -95,11 +96,9 @@ const ZoomRegionIface = <interface name={ZOOM_SERVICE_NAME}>
// '/org/gnome/Magnifier/ZoomRegion/zoomer1', etc.
let _zoomRegionInstanceCount = 0;
function ShellMagnifier() {
this._init();
}
const ShellMagnifier = new Lang.Class({
Name: 'ShellMagnifier',
ShellMagnifier.prototype = {
_init: function() {
this._zoomers = {};
@ -325,7 +324,7 @@ ShellMagnifier.prototype = {
// Drop the leading '#'.
return parseInt(colorString.slice(1), 16);
}
};
});
/**
* ShellMagnifierZoomRegion:
@ -333,11 +332,9 @@ ShellMagnifier.prototype = {
* @zoomerObjectPath: String that is the path to a DBus ZoomRegion.
* @zoomRegion: The actual zoom region associated with the object path.
*/
function ShellMagnifierZoomRegion(zoomerObjectPath, zoomRegion) {
this._init(zoomerObjectPath, zoomRegion);
}
const ShellMagnifierZoomRegion = new Lang.Class({
Name: 'ShellMagnifierZoomRegion',
ShellMagnifierZoomRegion.prototype = {
_init: function(zoomerObjectPath, zoomRegion) {
this._zoomRegion = zoomRegion;
@ -422,4 +419,4 @@ ShellMagnifierZoomRegion.prototype = {
destroy: function() {
this._dbusImpl.unexport();
}
};
});

View File

@ -83,11 +83,9 @@ function _fixMarkup(text, allowMarkup) {
return GLib.markup_escape_text(text, -1);
}
function URLHighlighter(text, lineWrap, allowMarkup) {
this._init(text, lineWrap, allowMarkup);
}
const URLHighlighter = new Lang.Class({
Name: 'URLHighlighter',
URLHighlighter.prototype = {
_init: function(text, lineWrap, allowMarkup) {
if (!text)
text = '';
@ -211,13 +209,11 @@ URLHighlighter.prototype = {
}
return -1;
}
};
});
function FocusGrabber() {
this._init();
}
const FocusGrabber = new Lang.Class({
Name: 'FocusGrabber',
FocusGrabber.prototype = {
_init: function() {
this.actor = null;
@ -351,7 +347,7 @@ FocusGrabber.prototype = {
this._togglingFocusGrabMode = false;
}
}
}
});
Signals.addSignalMethods(FocusGrabber.prototype);
// Notification:
@ -408,11 +404,9 @@ Signals.addSignalMethods(FocusGrabber.prototype);
// the content and the action area of the notification will be cleared.
// The content area is also always cleared if 'customContent' is false
// because it might contain the @banner that didn't fit in the banner mode.
function Notification(source, title, banner, params) {
this._init(source, title, banner, params);
}
const Notification = new Lang.Class({
Name: 'Notification',
Notification.prototype = {
IMAGE_SIZE: 125,
_init: function(source, title, banner, params) {
@ -953,14 +947,12 @@ Notification.prototype = {
this.actor.destroy();
this.actor._delegate = null;
}
};
});
Signals.addSignalMethods(Notification.prototype);
function Source(title) {
this._init(title);
}
const Source = new Lang.Class({
Name: 'MessageTraySource',
Source.prototype = {
ICON_SIZE: 24,
_init: function(title) {
@ -1142,14 +1134,12 @@ Source.prototype = {
_lastNotificationRemoved: function() {
this.destroy();
}
};
});
Signals.addSignalMethods(Source.prototype);
function SummaryItem(source) {
this._init(source);
}
const SummaryItem = new Lang.Class({
Name: 'SummaryItem',
SummaryItem.prototype = {
_init: function(source) {
this.source = source;
this.source.connect('notification-added', Lang.bind(this, this._notificationAddedToSource));
@ -1340,14 +1330,12 @@ SummaryItem.prototype = {
if (this.notificationStack.get_children().length > 0)
this.notificationStack.get_children()[0]._delegate.setIconVisible(true);
}
};
});
Signals.addSignalMethods(SummaryItem.prototype);
function MessageTray() {
this._init();
}
const MessageTray = new Lang.Class({
Name: 'MessageTray',
MessageTray.prototype = {
_init: function() {
this._presence = new GnomeSession.Presence(Lang.bind(this, function(proxy, error) {
this._onStatusChanged(proxy.status);
@ -2426,17 +2414,14 @@ MessageTray.prototype = {
if (this._clickedSummaryItem)
this._updateState();
}
};
});
function SystemNotificationSource() {
this._init();
}
SystemNotificationSource.prototype = {
__proto__: Source.prototype,
const SystemNotificationSource = new Lang.Class({
Name: 'SystemNotificationSource',
Extends: Source,
_init: function() {
Source.prototype._init.call(this, _("System Information"));
this.parent(_("System Information"));
this._setSummaryIcon(this.createNotificationIcon());
},
@ -2450,4 +2435,4 @@ SystemNotificationSource.prototype = {
open: function() {
this.destroy();
}
};
});

View File

@ -29,11 +29,9 @@ const State = {
FADED_OUT: 4
};
function ModalDialog() {
this._init();
}
const ModalDialog = new Lang.Class({
Name: 'ModalDialog',
ModalDialog.prototype = {
_init: function(params) {
params = Params.parse(params, { shellReactive: false,
styleClass: null });
@ -303,5 +301,5 @@ ModalDialog.prototype = {
})
});
}
};
});
Signals.addSignalMethods(ModalDialog.prototype);

View File

@ -32,15 +32,12 @@ const ModalDialog = imports.ui.modalDialog;
const PopupMenu = imports.ui.popupMenu;
const ShellEntry = imports.ui.shellEntry;
function NetworkSecretDialog() {
this._init.apply(this, arguments);
}
NetworkSecretDialog.prototype = {
__proto__: ModalDialog.ModalDialog.prototype,
const NetworkSecretDialog = new Lang.Class({
Name: 'NetworkSecretDialog',
Extends: ModalDialog.ModalDialog,
_init: function(agent, requestId, connection, settingName, hints) {
ModalDialog.ModalDialog.prototype._init.call(this, { styleClass: 'polkit-dialog' });
this.parent({ styleClass: 'polkit-dialog' });
this._agent = agent;
this._requestId = requestId;
@ -358,13 +355,11 @@ NetworkSecretDialog.prototype = {
return content;
}
};
});
function NetworkAgent() {
this._init.apply(this, arguments);
}
const NetworkAgent = new Lang.Class({
Name: 'NetworkAgent',
NetworkAgent.prototype = {
_init: function() {
this._native = new Shell.NetworkAgent({ auto_register: true,
identifier: 'org.gnome.Shell.NetworkAgent' });
@ -387,4 +382,4 @@ NetworkAgent.prototype = {
this._dialogs[requestId].close(global.get_current_time());
this._dialogs[requestId].destroy();
}
};
});

View File

@ -87,11 +87,9 @@ const rewriteRules = {
]
};
function NotificationDaemon() {
this._init();
}
const NotificationDaemon = new Lang.Class({
Name: 'NotificationDaemon',
NotificationDaemon.prototype = {
_init: function() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(NotificationDaemonIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/freedesktop/Notifications');
@ -474,17 +472,14 @@ NotificationDaemon.prototype = {
if (source)
source.destroy();
}
};
});
function Source(title, pid, sender) {
this._init(title, pid, sender);
}
Source.prototype = {
__proto__: MessageTray.Source.prototype,
const Source = new Lang.Class({
Name: 'NotificationDaemonSource',
Extends: MessageTray.Source,
_init: function(title, pid, sender) {
MessageTray.Source.prototype._init.call(this, title);
this.parent(title);
this._pid = pid;
if (sender)
@ -606,6 +601,6 @@ Source.prototype = {
this._nameWatcherId = 0;
}
MessageTray.Source.prototype.destroy.call(this);
this.parent();
}
};
});

View File

@ -46,11 +46,9 @@ const SwipeScrollResult = {
CLICK: 2
};
function ShellInfo() {
this._init();
}
const ShellInfo = new Lang.Class({
Name: 'ShellInfo',
ShellInfo.prototype = {
_init: function() {
this._source = null;
this._undoCallback = null;
@ -95,13 +93,11 @@ ShellInfo.prototype = {
this._source.notify(notification);
}
};
});
function Overview() {
this._init.apply(this, arguments);
}
const Overview = new Lang.Class({
Name: 'Overview',
Overview.prototype = {
_init : function(params) {
params = Params.parse(params, { isDummy: false });
@ -811,5 +807,5 @@ Overview.prototype = {
this._needsFakePointerEvent = false;
}
}
};
});
Signals.addSignalMethods(Overview.prototype);

View File

@ -3,6 +3,7 @@
const Cairo = imports.cairo;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Pango = imports.gi.Pango;
@ -98,11 +99,9 @@ function _unpremultiply(color) {
};
function AnimatedIcon(name, size) {
this._init(name, size);
}
const AnimatedIcon = new Lang.Class({
Name: 'AnimatedIcon',
AnimatedIcon.prototype = {
_init: function(name, size) {
this.actor = new St.Bin({ visible: false });
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
@ -139,13 +138,11 @@ AnimatedIcon.prototype = {
if (this._timeoutId)
Mainloop.source_remove(this._timeoutId);
}
};
});
function TextShadower() {
this._init();
}
const TextShadower = new Lang.Class({
Name: 'TextShadower',
TextShadower.prototype = {
_init: function() {
this.actor = new Shell.GenericContainer();
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
@ -225,7 +222,7 @@ TextShadower.prototype = {
child.allocate(childBox, flags);
}
}
};
});
/**
* AppMenuButton:
@ -235,18 +232,19 @@ TextShadower.prototype = {
* this menu also handles startup notification for it. So when we
* have an active startup notification, we switch modes to display that.
*/
function AppMenuButton() {
this._init();
}
const AppMenuButton = new Lang.Class({
Name: 'AppMenuButton',
Extends: PanelMenu.Button,
AppMenuButton.prototype = {
__proto__: PanelMenu.Button.prototype,
_init: function(menuManager) {
this.parent(0.0, true);
_init: function() {
PanelMenu.Button.prototype._init.call(this, 0.0);
this._startingApps = [];
this._menuManager = menuManager;
this._targetApp = null;
this._appMenuNotifyId = 0;
this._actionGroupNotifyId = 0;
let bin = new St.Bin({ name: 'appMenu' });
this.actor.add_actor(bin);
@ -271,10 +269,6 @@ AppMenuButton.prototype = {
this._iconBottomClip = 0;
this._quitMenu = new PopupMenu.PopupMenuItem('');
this.menu.addMenuItem(this._quitMenu);
this._quitMenu.connect('activate', Lang.bind(this, this._onQuit));
this._visible = !Main.overview.visible;
if (!this._visible)
this.actor.hide();
@ -453,12 +447,6 @@ AppMenuButton.prototype = {
}
},
_onQuit: function() {
if (this._targetApp == null)
return;
this._targetApp.request_quit();
},
_onAppStateChanged: function(appSys, app) {
let state = app.state;
if (state != Shell.AppState.STARTING) {
@ -520,8 +508,10 @@ AppMenuButton.prototype = {
}
if (targetApp == this._targetApp) {
if (targetApp && targetApp.get_state() != Shell.AppState.STARTING)
if (targetApp && targetApp.get_state() != Shell.AppState.STARTING) {
this.stopAnimation();
this._maybeSetMenu();
}
return;
}
@ -531,37 +521,67 @@ AppMenuButton.prototype = {
this._iconBox.hide();
this._label.setText('');
if (this._appMenuNotifyId)
this._targetApp.disconnect(this._appMenuNotifyId);
if (this._actionGroupNotifyId)
this._targetApp.disconnect(this._actionGroupNotifyId);
if (targetApp) {
this._appMenuNotifyId = targetApp.connect('notify::menu', Lang.bind(this, this._sync));
this._actionGroupNotifyId = targetApp.connect('notify::action-group', Lang.bind(this, this._sync));
}
this._targetApp = targetApp;
let icon = targetApp.get_faded_icon(2 * PANEL_ICON_SIZE);
this._label.setText(targetApp.get_name());
// TODO - _quit() doesn't really work on apps in state STARTING yet
this._quitMenu.label.set_text(_("Quit %s").format(targetApp.get_name()));
this._iconBox.set_child(icon);
this._iconBox.show();
if (targetApp.get_state() == Shell.AppState.STARTING)
this.startAnimation();
else
this._maybeSetMenu();
this.emit('changed');
},
_maybeSetMenu: function() {
let menu;
if (this._targetApp.action_group) {
if (this.menu instanceof PopupMenu.RemoteMenu &&
this.menu.actionGroup == this._targetApp.action_group)
return;
menu = new PopupMenu.RemoteMenu(this.actor, this._targetApp.menu, this._targetApp.action_group);
} else {
if (this.menu && !(this.menu instanceof PopupMenu.RemoteMenu))
return;
// fallback to older menu
menu = new PopupMenu.PopupMenu(this.actor, 0.0, St.Side.TOP, 0);
menu.addAction(_("Quit"), Lang.bind(this, function() {
this._targetApp.request_quit();
}));
}
this.setMenu(menu);
this._menuManager.addMenu(menu);
}
};
});
Signals.addSignalMethods(AppMenuButton.prototype);
// Activities button. Because everything else in the top bar is a
// PanelMenu.Button, it simplifies some things to make this be one too.
// We just hack it up to not actually have a menu attached to it.
function ActivitiesButton() {
this._init.apply(this, arguments);
}
ActivitiesButton.prototype = {
__proto__: PanelMenu.Button.prototype,
const ActivitiesButton = new Lang.Class({
Name: 'ActivitiesButton',
Extends: PanelMenu.Button,
_init: function() {
PanelMenu.Button.prototype._init.call(this, 0.0);
this.parent(0.0);
let container = new Shell.GenericContainer();
container.connect('get-preferred-width', Lang.bind(this, this._containerGetPreferredWidth));
@ -698,13 +718,11 @@ ActivitiesButton.prototype = {
Mainloop.source_remove(this._xdndTimeOut);
this._xdndTimeOut = 0;
}
};
});
function PanelCorner(panel, side) {
this._init(panel, side);
}
const PanelCorner = new Lang.Class({
Name: 'PanelCorner',
PanelCorner.prototype = {
_init: function(box, side) {
this._side = side;
@ -880,14 +898,12 @@ PanelCorner.prototype = {
this.actor.set_size(cornerRadius, innerBorderWidth + cornerRadius);
this.actor.set_anchor_point(0, innerBorderWidth);
}
};
});
function Panel() {
this._init();
}
const Panel = new Lang.Class({
Name: 'Panel',
Panel.prototype = {
_init : function() {
this.actor = new Shell.GenericContainer({ name: 'panel',
reactive: true });
@ -938,9 +954,8 @@ Panel.prototype = {
// more cleanly with the rest of the panel
this._menus.addMenu(this._activitiesButton.menu);
this._appMenu = new AppMenuButton();
this._appMenu = new AppMenuButton(this._menus);
this._leftBox.add(this._appMenu.actor);
this._menus.addMenu(this._appMenu.menu);
}
/* center */
@ -1114,5 +1129,4 @@ Panel.prototype = {
if (box && box._delegate instanceof PanelMenu.ButtonBox)
box.destroy();
},
};
});

View File

@ -11,11 +11,9 @@ const Main = imports.ui.main;
const Params = imports.misc.params;
const PopupMenu = imports.ui.popupMenu;
function ButtonBox(params) {
this._init.apply(this, arguments);
};
const ButtonBox = new Lang.Class({
Name: 'ButtonBox',
ButtonBox.prototype = {
_init: function(params) {
params = Params.parse(params, { style_class: 'panel-button' }, true);
this.actor = new Shell.GenericContainer(params);
@ -92,31 +90,45 @@ ButtonBox.prototype = {
child.allocate(childBox, flags);
},
}
});
function Button(menuAlignment) {
this._init(menuAlignment);
}
const Button = new Lang.Class({
Name: 'PanelMenuButton',
Extends: ButtonBox,
Button.prototype = {
__proto__: ButtonBox.prototype,
_init: function(menuAlignment) {
ButtonBox.prototype._init.call(this, { reactive: true,
can_focus: true,
track_hover: true });
_init: function(menuAlignment, dontCreateMenu) {
this.parent({ reactive: true,
can_focus: true,
track_hover: true });
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
this.actor.connect('key-press-event', Lang.bind(this, this._onSourceKeyPress));
this.menu = new PopupMenu.PopupMenu(this.actor, menuAlignment, St.Side.TOP);
this.menu.actor.add_style_class_name('panel-menu');
this.menu.connect('open-state-changed', Lang.bind(this, this._onOpenStateChanged));
this.menu.actor.connect('key-press-event', Lang.bind(this, this._onMenuKeyPress));
Main.uiGroup.add_actor(this.menu.actor);
this.menu.actor.hide();
if (dontCreateMenu)
this.menu = null;
else
this.setMenu(new PopupMenu.PopupMenu(this.actor, menuAlignment, St.Side.TOP, 0));
},
setMenu: function(menu) {
if (this.menu)
this.menu.destroy();
this.menu = menu;
if (this.menu) {
this.menu.actor.add_style_class_name('panel-menu');
this.menu.connect('open-state-changed', Lang.bind(this, this._onOpenStateChanged));
this.menu.actor.connect('key-press-event', Lang.bind(this, this._onMenuKeyPress));
Main.uiGroup.add_actor(this.menu.actor);
this.menu.actor.hide();
}
},
_onButtonPress: function(actor, event) {
if (!this.menu)
return;
if (!this.menu.isOpen) {
// Setting the max-height won't do any good if the minimum height of the
// menu is higher then the screen; it's useful if part of the menu is
@ -130,6 +142,9 @@ Button.prototype = {
},
_onSourceKeyPress: function(actor, event) {
if (!this.menu)
return false;
let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_space || symbol == Clutter.KEY_Return) {
this.menu.toggle();
@ -175,7 +190,7 @@ Button.prototype = {
this.emit('destroy');
}
};
});
Signals.addSignalMethods(Button.prototype);
/* SystemStatusButton:
@ -184,15 +199,13 @@ Signals.addSignalMethods(Button.prototype);
* volume, bluetooth...), which is just a PanelMenuButton with an
* icon and a tooltip
*/
function SystemStatusButton() {
this._init.apply(this, arguments);
}
SystemStatusButton.prototype = {
__proto__: Button.prototype,
const SystemStatusButton = new Lang.Class({
Name: 'SystemStatusButton',
Extends: Button,
_init: function(iconName,tooltipText) {
Button.prototype._init.call(this, 0.0);
this.parent(0.0);
this._iconActor = new St.Icon({ icon_name: iconName,
icon_type: St.IconType.SYMBOLIC,
style_class: 'system-status-icon' });
@ -219,4 +232,4 @@ SystemStatusButton.prototype = {
this.tooltip = null;
}
}
};
});

View File

@ -22,11 +22,9 @@ const Util = imports.misc.util;
* @iconFactory: A JavaScript callback which will create an icon texture given a size parameter
* @launch: A JavaScript callback to launch the entry
*/
function PlaceInfo(id, name, iconFactory, launch) {
this._init(id, name, iconFactory, launch);
}
const PlaceInfo = new Lang.Class({
Name: 'PlaceInfo',
PlaceInfo.prototype = {
_init: function(id, name, iconFactory, launch) {
this.id = id;
this.name = name;
@ -55,7 +53,7 @@ PlaceInfo.prototype = {
isRemovable: function() {
return false;
}
};
});
// Helper function to translate launch parameters into a GAppLaunchContext
function _makeLaunchContext(params)
@ -72,12 +70,9 @@ function _makeLaunchContext(params)
return launchContext;
}
function PlaceDeviceInfo(mount) {
this._init(mount);
}
PlaceDeviceInfo.prototype = {
__proto__: PlaceInfo.prototype,
const PlaceDeviceInfo = new Lang.Class({
Name: 'PlaceDeviceInfo',
Extends: PlaceInfo,
_init: function(mount) {
this._mount = mount;
@ -123,13 +118,11 @@ PlaceDeviceInfo.prototype = {
_("Retry"));
}
}
};
});
function PlacesManager() {
this._init();
}
const PlacesManager = new Lang.Class({
Name: 'PlacesManager',
PlacesManager.prototype = {
_init: function() {
this._defaultPlaces = [];
this._mounts = [];
@ -360,19 +353,15 @@ PlacesManager.prototype = {
_removeById: function(sourceArray, id) {
sourceArray.splice(this._lookupIndexById(sourceArray, id), 1);
}
};
});
Signals.addSignalMethods(PlacesManager.prototype);
function PlaceSearchProvider() {
this._init();
}
PlaceSearchProvider.prototype = {
__proto__: Search.SearchProvider.prototype,
const PlaceSearchProvider = new Lang.Class({
Name: 'PlaceSearchProvider',
Extends: Search.SearchProvider,
_init: function() {
Search.SearchProvider.prototype._init.call(this, _("PLACES & DEVICES"));
this.parent(_("PLACES & DEVICES"));
},
getResultMeta: function(resultId) {
@ -434,4 +423,4 @@ PlaceSearchProvider.prototype = {
let places = previousResults.map(function (id) { return Main.placesManager.lookupPlaceById(id); });
return this._searchPlaces(places, terms);
}
};
});

View File

@ -36,15 +36,12 @@ const PolkitAgent = imports.gi.PolkitAgent;
const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry;
function AuthenticationDialog(actionId, message, cookie, userNames) {
this._init(actionId, message, cookie, userNames);
}
AuthenticationDialog.prototype = {
__proto__: ModalDialog.ModalDialog.prototype,
const AuthenticationDialog = new Lang.Class({
Name: 'AuthenticationDialog',
Extends: ModalDialog.ModalDialog,
_init: function(actionId, message, cookie, userNames) {
ModalDialog.ModalDialog.prototype._init.call(this, { styleClass: 'polkit-dialog' });
this.parent({ styleClass: 'polkit-dialog' });
this.actionId = actionId;
this.message = message;
@ -335,15 +332,12 @@ AuthenticationDialog.prototype = {
this.close(global.get_current_time());
this._emitDone(false, true);
},
};
});
Signals.addSignalMethods(AuthenticationDialog.prototype);
function AuthenticationAgent() {
this._init();
}
const AuthenticationAgent = new Lang.Class({
Name: 'AuthenticationAgent',
AuthenticationAgent.prototype = {
_init: function() {
this._native = new Shell.PolkitAuthenticationAgent();
this._native.connect('initiate', Lang.bind(this, this._onInitiate));
@ -404,7 +398,7 @@ AuthenticationAgent.prototype = {
this._reallyCompleteRequest(wasDismissed);
}
}
}
});
function init() {
let agent = new AuthenticationAgent();

View File

@ -2,7 +2,9 @@
const Cairo = imports.cairo;
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@ -26,11 +28,9 @@ function _ensureStyle(actor) {
actor.ensure_style();
}
function PopupBaseMenuItem(params) {
this._init(params);
}
const PopupBaseMenuItem = new Lang.Class({
Name: 'PopupBaseMenuItem',
PopupBaseMenuItem.prototype = {
_init: function (params) {
params = Params.parse (params, { reactive: true,
activate: true,
@ -377,33 +377,27 @@ PopupBaseMenuItem.prototype = {
x -= availWidth + this._spacing;
}
}
};
});
Signals.addSignalMethods(PopupBaseMenuItem.prototype);
function PopupMenuItem() {
this._init.apply(this, arguments);
}
PopupMenuItem.prototype = {
__proto__: PopupBaseMenuItem.prototype,
const PopupMenuItem = new Lang.Class({
Name: 'PopupMenuItem',
Extends: PopupBaseMenuItem,
_init: function (text, params) {
PopupBaseMenuItem.prototype._init.call(this, params);
this.parent(params);
this.label = new St.Label({ text: text });
this.addActor(this.label);
}
};
});
function PopupSeparatorMenuItem() {
this._init();
}
PopupSeparatorMenuItem.prototype = {
__proto__: PopupBaseMenuItem.prototype,
const PopupSeparatorMenuItem = new Lang.Class({
Name: 'PopupSeparatorMenuItem',
Extends: PopupBaseMenuItem,
_init: function () {
PopupBaseMenuItem.prototype._init.call(this, { reactive: false });
this.parent({ reactive: false });
this._drawingArea = new St.DrawingArea({ style_class: 'popup-separator-menu-item' });
this.addActor(this._drawingArea, { span: -1, expand: true });
@ -429,22 +423,19 @@ PopupSeparatorMenuItem.prototype = {
cr.rectangle(margin, gradientOffset, gradientWidth, gradientHeight);
cr.fill();
}
};
});
const PopupAlternatingMenuItemState = {
DEFAULT: 0,
ALTERNATIVE: 1
}
function PopupAlternatingMenuItem() {
this._init.apply(this, arguments);
}
PopupAlternatingMenuItem.prototype = {
__proto__: PopupBaseMenuItem.prototype,
const PopupAlternatingMenuItem = new Lang.Class({
Name: 'PopupAlternatingMenuItem',
Extends: PopupBaseMenuItem,
_init: function(text, alternateText, params) {
PopupBaseMenuItem.prototype._init.call(this, params);
this.parent(params);
this.actor.add_style_class_name('popup-alternating-menu-item');
this._text = text;
@ -530,17 +521,14 @@ PopupAlternatingMenuItem.prototype = {
this._updateLabel();
}
};
});
function PopupSliderMenuItem() {
this._init.apply(this, arguments);
}
PopupSliderMenuItem.prototype = {
__proto__: PopupBaseMenuItem.prototype,
const PopupSliderMenuItem = new Lang.Class({
Name: 'PopupSliderMenuItem',
Extends: PopupBaseMenuItem,
_init: function(value) {
PopupBaseMenuItem.prototype._init.call(this, { activate: false });
this.parent({ activate: false });
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
@ -716,13 +704,11 @@ PopupSliderMenuItem.prototype = {
}
return false;
}
};
});
function Switch() {
this._init.apply(this, arguments);
}
const Switch = new Lang.Class({
Name: 'Switch',
Switch.prototype = {
_init: function(state) {
this.actor = new St.Bin({ style_class: 'toggle-switch' });
// Translators: this MUST be either "toggle-switch-us"
@ -745,17 +731,14 @@ Switch.prototype = {
toggle: function() {
this.setToggleState(!this.state);
}
};
});
function PopupSwitchMenuItem() {
this._init.apply(this, arguments);
}
PopupSwitchMenuItem.prototype = {
__proto__: PopupBaseMenuItem.prototype,
const PopupSwitchMenuItem = new Lang.Class({
Name: 'PopupSwitchMenuItem',
Extends: PopupBaseMenuItem,
_init: function(text, active, params) {
PopupBaseMenuItem.prototype._init.call(this, params);
this.parent(params);
this.label = new St.Label({ text: text });
this._switch = new Switch(active);
@ -790,7 +773,7 @@ PopupSwitchMenuItem.prototype = {
this.toggle();
}
PopupBaseMenuItem.prototype.activate.call(this, event);
this.parent(event);
},
toggle: function() {
@ -805,17 +788,14 @@ PopupSwitchMenuItem.prototype = {
setToggleState: function(state) {
this._switch.setToggleState(state);
}
};
});
function PopupImageMenuItem() {
this._init.apply(this, arguments);
}
PopupImageMenuItem.prototype = {
__proto__: PopupBaseMenuItem.prototype,
const PopupImageMenuItem = new Lang.Class({
Name: 'PopupImageMenuItem',
Extends: PopupBaseMenuItem,
_init: function (text, iconName, params) {
PopupBaseMenuItem.prototype._init.call(this, params);
this.parent(params);
this.label = new St.Label({ text: text });
this.addActor(this.label);
@ -828,13 +808,12 @@ PopupImageMenuItem.prototype = {
setIcon: function(name) {
this._icon.icon_name = name;
}
};
});
function PopupMenuBase() {
throw new TypeError('Trying to instantiate abstract class PopupMenuBase');
}
const PopupMenuBase = new Lang.Class({
Name: 'PopupMenuBase',
Abstract: true,
PopupMenuBase.prototype = {
_init: function(sourceActor, styleClass) {
this.sourceActor = sourceActor;
@ -1139,18 +1118,15 @@ PopupMenuBase.prototype = {
this.emit('destroy');
}
};
});
Signals.addSignalMethods(PopupMenuBase.prototype);
function PopupMenu() {
this._init.apply(this, arguments);
}
PopupMenu.prototype = {
__proto__: PopupMenuBase.prototype,
const PopupMenu = new Lang.Class({
Name: 'PopupMenu',
Extends: PopupMenuBase,
_init: function(sourceActor, arrowAlignment, arrowSide) {
PopupMenuBase.prototype._init.call (this, sourceActor, 'popup-menu-content');
this.parent(sourceActor, 'popup-menu-content');
this._arrowAlignment = arrowAlignment;
this._arrowSide = arrowSide;
@ -1235,17 +1211,14 @@ PopupMenu.prototype = {
this.isOpen = false;
this.emit('open-state-changed', false);
}
};
});
function PopupSubMenu() {
this._init.apply(this, arguments);
}
PopupSubMenu.prototype = {
__proto__: PopupMenuBase.prototype,
const PopupSubMenu = new Lang.Class({
Name: 'PopupSubMenu',
Extends: PopupMenuBase,
_init: function(sourceActor, sourceArrow) {
PopupMenuBase.prototype._init.call(this, sourceActor);
this.parent(sourceActor);
this._arrow = sourceArrow;
this._arrow.rotation_center_z_gravity = Clutter.Gravity.CENTER;
@ -1400,7 +1373,7 @@ PopupSubMenu.prototype = {
return false;
}
};
});
/**
* PopupMenuSection:
@ -1410,15 +1383,12 @@ PopupSubMenu.prototype = {
* can add it to another menu), but is completely transparent
* to the user
*/
function PopupMenuSection() {
this._init.apply(this, arguments);
}
PopupMenuSection.prototype = {
__proto__: PopupMenuBase.prototype,
const PopupMenuSection = new Lang.Class({
Name: 'PopupMenuSection',
Extends: PopupMenuBase,
_init: function() {
PopupMenuBase.prototype._init.call(this);
this.parent();
this.actor = this.box;
this.actor._delegate = this;
@ -1429,17 +1399,14 @@ PopupMenuSection.prototype = {
// corresponding signal so children can still pick it up
open: function(animate) { this.emit('open-state-changed', true); },
close: function() { this.emit('open-state-changed', false); },
}
});
function PopupSubMenuMenuItem() {
this._init.apply(this, arguments);
}
PopupSubMenuMenuItem.prototype = {
__proto__: PopupBaseMenuItem.prototype,
const PopupSubMenuMenuItem = new Lang.Class({
Name: 'PopupSubMenuMenuItem',
Extends: PopupBaseMenuItem,
_init: function(text) {
PopupBaseMenuItem.prototype._init.call(this);
this.parent();
this.actor.add_style_class_name('popup-submenu-menu-item');
@ -1461,7 +1428,8 @@ PopupSubMenuMenuItem.prototype = {
destroy: function() {
this.menu.destroy();
PopupBaseMenuItem.prototype.destroy.call(this);
this.parent();
},
_onKeyPressEvent: function(actor, event) {
@ -1476,7 +1444,7 @@ PopupSubMenuMenuItem.prototype = {
return true;
}
return PopupBaseMenuItem.prototype._onKeyPressEvent.call(this, actor, event);
return this.parent(actor, event);
},
activate: function(event) {
@ -1486,18 +1454,15 @@ PopupSubMenuMenuItem.prototype = {
_onButtonReleaseEvent: function(actor) {
this.menu.toggle();
}
};
});
function PopupComboMenu() {
this._init.apply(this, arguments);
}
PopupComboMenu.prototype = {
__proto__: PopupMenuBase.prototype,
const PopupComboMenu = new Lang.Class({
Name: 'PopupComboMenu',
Extends: PopupMenuBase,
_init: function(sourceActor) {
PopupMenuBase.prototype._init.call(this,
sourceActor, 'popup-combo-menu');
this.parent(sourceActor, 'popup-combo-menu');
this.actor = this.box;
this.actor._delegate = this;
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
@ -1602,17 +1567,14 @@ PopupComboMenu.prototype = {
getItemVisible: function(position) {
return this._getMenuItems()[position].actor.visible;
}
};
});
function PopupComboBoxMenuItem() {
this._init.apply(this, arguments);
}
PopupComboBoxMenuItem.prototype = {
__proto__: PopupBaseMenuItem.prototype,
const PopupComboBoxMenuItem = new Lang.Class({
Name: 'PopupComboBoxMenuItem',
Extends: PopupBaseMenuItem,
_init: function (params) {
PopupBaseMenuItem.prototype._init.call(this, params);
this.parent(params);
this._itemBox = new Shell.Stack();
this.addActor(this._itemBox);
@ -1730,16 +1692,254 @@ PopupComboBoxMenuItem.prototype = {
this.setActiveItem(position);
this.emit('active-item-changed', position);
}
};
});
/**
* RemoteMenu:
*
* A PopupMenu that tracks a GMenuModel and shows its actions
* (exposed by GApplication/GActionGroup)
*/
const RemoteMenu = new Lang.Class({
Name: 'RemoteMenu',
Extends: PopupMenu,
_init: function(sourceActor, model, actionGroup) {
this.parent(sourceActor, 0.0, St.Side.TOP);
this.model = model;
this.actionGroup = actionGroup;
this._actions = { };
this._modelChanged(this.model, 0, 0, this.model.get_n_items(), this);
this._actionStateChangeId = this.actionGroup.connect('action-state-changed', Lang.bind(this, this._actionStateChanged));
this._actionEnableChangeId = this.actionGroup.connect('action-enabled-changed', Lang.bind(this, this._actionEnabledChanged));
},
destroy: function() {
if (this._actionStateChangeId) {
this.actionGroup.disconnect(this._actionStateChangeId);
this._actionStateChangeId = 0;
}
if (this._actionEnableChangeId) {
this.actionGroup.disconnect(this._actionEnableChangeId);
this._actionEnableChangeId = 0;
}
this.parent();
},
_createMenuItem: function(model, index) {
let section_link = model.get_item_link(index, Gio.MENU_LINK_SECTION);
if (section_link) {
let item = new PopupMenuSection();
this._modelChanged(section_link, 0, 0, section_link.get_n_items(), item);
return [item, true, ''];
}
// labels are not checked for existance, as they're required for all items
let label = model.get_item_attribute_value(index, Gio.MENU_ATTRIBUTE_LABEL, null).deep_unpack();
// remove all underscores that are not followed by another underscore
label = label.replace(/_([^_])/, '$1');
let submenu_link = model.get_item_link(index, Gio.MENU_LINK_SUBMENU);
if (submenu_link) {
let item = new PopupSubMenuMenuItem(label);
this._modelChanged(submenu_link, 0, 0, submenu_link.get_n_items(), item.menu);
return [item, false, ''];
}
let action_id = model.get_item_attribute_value(index, Gio.MENU_ATTRIBUTE_ACTION, null).deep_unpack();
if (!this.actionGroup.has_action(action_id)) {
// the action may not be there yet, wait for action-added
return [null, false, 'action-added'];
}
if (!this._actions[action_id])
this._actions[action_id] = { enabled: this.actionGroup.get_action_enabled(action_id),
state: this.actionGroup.get_action_state(action_id),
items: [ ],
};
let action = this._actions[action_id];
let item, target, destroyId, specificSignalId;
if (action.state) {
// Docs have get_state_hint(), except that the DBus protocol
// has no provision for it (so ShellApp does not implement it,
// and neither GApplication), and g_action_get_state_hint()
// always returns null
// Funny :)
switch (String.fromCharCode(action.state.classify())) {
case 'b':
item = new PopupSwitchMenuItem(label, action.state.get_boolean());
action.items.push(item);
specificSignalId = item.connect('toggled', Lang.bind(this, function(item) {
this.actionGroup.activate_action(action_id, null);
}));
break;
case 's':
item = new PopupMenuItem(label);
item._remoteTarget = model.get_item_attribute_value(index, Gio.MENU_ATTRIBUTE_TARGET, null).deep_unpack();
action.items.push(item);
item.setShowDot(action.state.deep_unpack() == item._remoteTarget);
specificSignalId = item.connect('activate', Lang.bind(this, function(item) {
this.actionGroup.activate_action(action_id, GLib.Variant.new_string(item._remoteTarget));
}));
break;
default:
log('Action "%s" has state of type %s, which is not supported'.format(action_id, action.state.get_type_string()));
return [null, false, 'action-state-changed'];
}
} else {
target = model.get_item_attribute_value(index, Gio.MENU_ATTRIBUTE_TARGET, null);
item = new PopupMenuItem(label);
action.items.push(item);
specificSignalId = item.connect('activate', Lang.bind(this, function() {
this.actionGroup.activate_action(action_id, target);
}));
}
item.actor.reactive = item.actor.can_focus = action.enabled;
if (action.enabled)
item.actor.remove_style_pseudo_class('insensitive');
else
item.actor.add_style_pseudo_class('insensitive');
destroyId = item.connect('destroy', Lang.bind(this, function() {
item.disconnect(destroyId);
item.disconnect(specificSignalId);
let pos = action.items.indexOf(item);
if (pos != -1)
action.items.splice(pos, 1);
}));
return [item, false, ''];
},
_modelChanged: function(model, position, removed, added, target) {
let j, k;
let j0, k0;
let currentItems = target._getMenuItems();
for (j0 = 0, k0 = 0; j0 < position; j0++, k0++) {
if (currentItems[k0] instanceof PopupSeparatorMenuItem)
k0++;
}
if (removed == -1) {
// special flag to indicate we should destroy everything
for (k = k0; k < currentItems.length; k++)
currentItems[k].destroy();
} else {
for (j = j0, k = k0; j < j0 + removed; j++, k++) {
currentItems[k].destroy();
if (currentItems[k] instanceof PopupSeparatorMenuItem)
j--;
}
}
for (j = j0, k = k0; j < j0 + added; j++, k++) {
let [item, addSeparator, changeSignal] = this._createMenuItem(model, j);
if (item) {
// separators must be added in the parent to make autohiding work
if (addSeparator) {
target.addMenuItem(new PopupSeparatorMenuItem(), k+1);
k++;
}
target.addMenuItem(item, k);
if (addSeparator) {
target.addMenuItem(new PopupSeparatorMenuItem(), k+1);
k++;
}
} else if (changeSignal) {
let signalId = this.actionGroup.connect(changeSignal, Lang.bind(this, function() {
this.actionGroup.disconnect(signalId);
// force a full update
this._modelChanged(model, 0, -1, model.get_n_items(), target);
}));
}
}
if (!model._changedId) {
model._changedId = model.connect('items-changed', Lang.bind(this, this._modelChanged, target));
model._destroyId = target.connect('destroy', function() {
if (model._changedId)
model.disconnect(model._changedId);
if (model._destroyId)
target.disconnect(model._destroyId);
model._changedId = 0;
model._destroyId = 0;
});
}
if (target instanceof PopupMenuSection) {
target.actor.visible = target.numMenuItems != 0;
} else {
let sourceItem = target.sourceActor._delegate;
if (sourceItem instanceof PopupSubMenuMenuItem)
sourceItem.actor.visible = target.numMenuItems != 0;
}
},
_actionStateChanged: function(actionGroup, action_id) {
let action = this._actions[action_id];
if (!action)
return;
action.state = actionGroup.get_action_state(action_id);
if (action.items.length) {
switch (String.fromCharCode(action.state.classify())) {
case 'b':
for (let i = 0; i < action.items.length; i++)
action.items[i].setToggleState(action.state.get_boolean());
break;
case 'd':
for (let i = 0; i < action.items.length; i++)
action.items[i].setValue(action.state.get_double());
break;
case 's':
for (let i = 0; i < action.items.length; i++)
action.items[i].setShowDot(action.items[i]._remoteTarget == action.state.deep_unpack());
}
}
},
_actionEnabledChanged: function(actionGroup, action_id) {
let action = this._actions[action_id];
if (!action)
return;
action.enabled = actionGroup.get_action_enabled(action_id);
if (action.items.length) {
for (let i = 0; i < action.items.length; i++) {
let item = action.items[i];
item.actor.reactive = item.actor.can_focus = action.enabled;
if (action.enabled)
item.actor.remove_style_pseudo_class('insensitive');
else
item.actor.add_style_pseudo_class('insensitive');
}
}
}
});
/* Basic implementation of a menu manager.
* Call addMenu to add menus
*/
function PopupMenuManager(owner) {
this._init(owner);
}
const PopupMenuManager = new Lang.Class({
Name: 'PopupMenuManager',
PopupMenuManager.prototype = {
_init: function(owner) {
this._owner = owner;
this.grabbed = false;
@ -2011,4 +2211,4 @@ PopupMenuManager.prototype = {
if (this._activeMenu != null)
this._activeMenu.close(true);
}
};
});

View File

@ -30,11 +30,9 @@ const EXEC_ARG_KEY = 'exec-arg';
const DIALOG_GROW_TIME = 0.1;
function CommandCompleter() {
this._init();
}
const CommandCompleter = new Lang.Class({
Name: 'CommandCompleter',
CommandCompleter.prototype = {
_init : function() {
this._changedCount = 0;
this._paths = GLib.getenv('PATH').split(':');
@ -162,16 +160,14 @@ CommandCompleter.prototype = {
return common.substr(text.length);
return common;
}
};
});
function RunDialog() {
this._init();
}
const RunDialog = new Lang.Class({
Name: 'RunDialog',
Extends: ModalDialog.ModalDialog,
RunDialog.prototype = {
__proto__: ModalDialog.ModalDialog.prototype,
_init : function() {
ModalDialog.ModalDialog.prototype._init.call(this, { styleClass: 'run-dialog' });
this.parent({ styleClass: 'run-dialog' });
this._lockdownSettings = new Gio.Settings({ schema: LOCKDOWN_SCHEMA });
this._terminalSettings = new Gio.Settings({ schema: TERMINAL_SCHEMA });
@ -384,8 +380,7 @@ __proto__: ModalDialog.ModalDialog.prototype,
if (this._lockdownSettings.get_boolean(DISABLE_COMMAND_LINE_KEY))
return;
ModalDialog.ModalDialog.prototype.open.call(this);
this.parent();
},
};
});
Signals.addSignalMethods(RunDialog.prototype);

View File

@ -23,11 +23,9 @@ const MatchType = {
MULTIPLE_PREFIX: 4
};
function SearchResultDisplay(provider) {
this._init(provider);
}
const SearchResultDisplay = new Lang.Class({
Name: 'SearchResultDisplay',
SearchResultDisplay.prototype = {
_init: function(provider) {
this.provider = provider;
this.actor = null;
@ -96,7 +94,7 @@ SearchResultDisplay.prototype = {
activateSelected: function() {
throw new Error('Not implemented');
}
};
});
/**
* SearchProvider:
@ -105,11 +103,9 @@ SearchResultDisplay.prototype = {
* to the search system, then call registerProvider()
* in SearchSystem with an instance.
*/
function SearchProvider(title) {
this._init(title);
}
const SearchProvider = new Lang.Class({
Name: 'SearchProvider',
SearchProvider.prototype = {
_init: function(title) {
this.title = title;
this.searchSystem = null;
@ -243,14 +239,12 @@ SearchProvider.prototype = {
activateResult: function(id) {
throw new Error('Not implemented');
}
};
});
Signals.addSignalMethods(SearchProvider.prototype);
function OpenSearchSystem() {
this._init();
}
const OpenSearchSystem = new Lang.Class({
Name: 'OpenSearchSystem',
OpenSearchSystem.prototype = {
_init: function() {
this._providers = [];
global.settings.connect('changed::' + DISABLED_OPEN_SEARCH_PROVIDERS_KEY, Lang.bind(this, this._refresh));
@ -338,14 +332,12 @@ OpenSearchSystem.prototype = {
}
}));
}
}
});
Signals.addSignalMethods(OpenSearchSystem.prototype);
function SearchSystem() {
this._init();
}
const SearchSystem = new Lang.Class({
Name: 'SearchSystem',
SearchSystem.prototype = {
_init: function() {
this._providers = [];
this.reset();
@ -433,5 +425,5 @@ SearchSystem.prototype = {
this._previousResults = results;
this.emit('search-completed', results);
},
};
});
Signals.addSignalMethods(SearchSystem.prototype);

View File

@ -15,11 +15,9 @@ const Search = imports.ui.search;
const MAX_SEARCH_RESULTS_ROWS = 1;
function SearchResult(provider, metaInfo, terms) {
this._init(provider, metaInfo, terms);
}
const SearchResult = new Lang.Class({
Name: 'SearchResult',
SearchResult.prototype = {
_init: function(provider, metaInfo, terms) {
this.provider = provider;
this.metaInfo = metaInfo;
@ -97,18 +95,16 @@ SearchResult.prototype = {
else
this.provider.activateResult(this.metaInfo.id, params);
}
};
});
function GridSearchResults(provider, grid) {
this._init(provider, grid);
}
GridSearchResults.prototype = {
__proto__: Search.SearchResultDisplay.prototype,
const GridSearchResults = new Lang.Class({
Name: 'GridSearchResults',
Extends: Search.SearchResultDisplay,
_init: function(provider, grid) {
Search.SearchResultDisplay.prototype._init.call(this, provider);
this.parent(provider);
this._grid = grid || new IconGrid.IconGrid({ rowLimit: MAX_SEARCH_RESULTS_ROWS,
xAlign: St.Align.START });
this.actor = new St.Bin({ x_align: St.Align.START });
@ -179,14 +175,11 @@ GridSearchResults.prototype = {
let targetActor = this._grid.getItemAtIndex(this.selectionIndex);
targetActor._delegate.activate();
}
};
});
const SearchResults = new Lang.Class({
Name: 'SearchResults',
function SearchResults(searchSystem, openSearchSystem) {
this._init(searchSystem, openSearchSystem);
}
SearchResults.prototype = {
_init: function(searchSystem, openSearchSystem) {
this._searchSystem = searchSystem;
this._searchSystem.connect('search-updated', Lang.bind(this, this._updateCurrentResults));
@ -486,4 +479,4 @@ SearchResults.prototype = {
resultDisplay.activateSelected();
Main.overview.hide();
}
};
});

View File

@ -66,11 +66,9 @@ const GnomeShellIface = <interface name="org.gnome.Shell">
</signal>
</interface>;
function GnomeShell() {
this._init();
}
const GnomeShell = new Lang.Class({
Name: 'GnomeShellDBus',
GnomeShell.prototype = {
_init: function() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
@ -230,4 +228,4 @@ GnomeShell.prototype = {
this._dbusImpl.emit_signal('ExtensionStatusChanged',
GLib.Variant.new('(sis)', [newState.uuid, newState.state, newState.error]));
}
};
});

View File

@ -7,18 +7,14 @@ const Main = imports.ui.main;
const Params = imports.misc.params;
const PopupMenu = imports.ui.popupMenu;
function _EntryMenu(entry, params) {
this._init(entry, params);
};
_EntryMenu.prototype = {
__proto__: PopupMenu.PopupMenu.prototype,
const _EntryMenu = new Lang.Class({
Name: 'ShellEntryMenu',
Extends: PopupMenu.PopupMenu,
_init: function(entry, params) {
params = Params.parse (params, { isPassword: false });
PopupMenu.PopupMenu.prototype._init.call(this, entry, 0, St.Side.TOP);
this.parent(entry, 0, St.Side.TOP);
this.actor.add_style_class_name('entry-context-menu');
@ -60,7 +56,7 @@ _EntryMenu.prototype = {
if (!this.actor.navigate_focus(null, direction, false))
this.actor.grab_key_focus();
PopupMenu.PopupMenu.prototype.open.call(this);
this.parent();
},
_updateCopyItem: function() {
@ -103,8 +99,7 @@ _EntryMenu.prototype = {
let visible = !!(this._entry.clutter_text.password_char);
this._entry.clutter_text.set_password_char(visible ? '' : '\u25cf');
}
};
});
function _setMenuAlignment(entry, stageX) {
let [success, entryX, entryY] = entry.transform_stage_point(stageX, 0);

View File

@ -50,11 +50,9 @@ function _setLabelsForMessage(dialog, message) {
/* -------------------------------------------------------- */
function ListItem(app) {
this._init(app);
}
const ListItem = new Lang.Class({
Name: 'ListItem',
ListItem.prototype = {
_init: function(app) {
this._app = app;
@ -86,14 +84,12 @@ ListItem.prototype = {
this.emit('activate');
this._app.activate();
}
};
});
Signals.addSignalMethods(ListItem.prototype);
function ShellMountOperation(source, params) {
this._init(source, params);
}
const ShellMountOperation = new Lang.Class({
Name: 'ShellMountOperation',
ShellMountOperation.prototype = {
_init: function(source, params) {
params = Params.parse(params, { reaskPassword: false });
@ -190,17 +186,14 @@ ShellMountOperation.prototype = {
this._processesDialog.update(message, processes, choices);
},
}
});
function ShellMountQuestionDialog(icon) {
this._init(icon);
}
ShellMountQuestionDialog.prototype = {
__proto__: ModalDialog.ModalDialog.prototype,
const ShellMountQuestionDialog = new Lang.Class({
Name: 'ShellMountQuestionDialog',
Extends: ModalDialog.ModalDialog,
_init: function(icon) {
ModalDialog.ModalDialog.prototype._init.call(this, { styleClass: 'mount-question-dialog' });
this.parent({ styleClass: 'mount-question-dialog' });
let mainContentLayout = new St.BoxLayout();
this.contentLayout.add(mainContentLayout, { x_fill: true,
@ -236,19 +229,16 @@ ShellMountQuestionDialog.prototype = {
_setLabelsForMessage(this, message);
_setButtonsForChoices(this, choices);
}
}
});
Signals.addSignalMethods(ShellMountQuestionDialog.prototype);
function ShellMountPasswordSource(message, icon, reaskPassword) {
this._init(message, icon, reaskPassword);
}
ShellMountPasswordSource.prototype = {
__proto__: MessageTray.Source.prototype,
const ShellMountPasswordSource = new Lang.Class({
Name: 'ShellMountPasswordSource',
Extends: MessageTray.Source,
_init: function(message, icon, reaskPassword) {
let strings = message.split('\n');
MessageTray.Source.prototype._init.call(this, strings[0]);
this.parent(strings[0]);
this._notification = new ShellMountPasswordNotification(this, strings, icon, reaskPassword);
@ -256,21 +246,15 @@ ShellMountPasswordSource.prototype = {
Main.messageTray.add(this);
this.notify(this._notification);
},
}
});
Signals.addSignalMethods(ShellMountPasswordSource.prototype);
function ShellMountPasswordNotification(source, strings, icon, reaskPassword) {
this._init(source, strings, icon, reaskPassword);
}
ShellMountPasswordNotification.prototype = {
__proto__: MessageTray.Notification.prototype,
const ShellMountPasswordNotification = new Lang.Class({
Name: 'ShellMountPasswordNotification',
Extends: MessageTray.Notification,
_init: function(source, strings, icon, reaskPassword) {
MessageTray.Notification.prototype._init.call(this, source,
strings[0], null,
{ customContent: true,
icon: icon });
this.parent(source, strings[0], null, { customContent: true, icon: icon });
// set the notification to transient and urgent, so that it
// expands out
@ -305,17 +289,14 @@ ShellMountPasswordNotification.prototype = {
this.source.emit('password-ready', text);
}
}
});
function ShellProcessesDialog(icon) {
this._init(icon);
}
ShellProcessesDialog.prototype = {
__proto__: ModalDialog.ModalDialog.prototype,
const ShellProcessesDialog = new Lang.Class({
Name: 'ShellProcessesDialog',
Extends: ModalDialog.ModalDialog,
_init: function(icon) {
ModalDialog.ModalDialog.prototype._init.call(this, { styleClass: 'show-processes-dialog' });
this.parent({ styleClass: 'show-processes-dialog' });
let mainContentLayout = new St.BoxLayout();
this.contentLayout.add(mainContentLayout, { x_fill: true,
@ -401,5 +382,5 @@ ShellProcessesDialog.prototype = {
_setLabelsForMessage(this, message);
_setButtonsForChoices(this, choices);
}
}
});
Signals.addSignalMethods(ShellProcessesDialog.prototype);

View File

@ -1,6 +1,5 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DBus = imports.dbus;
const GDesktopEnums = imports.gi.GDesktopEnums;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
@ -40,15 +39,12 @@ const KEY_TEXT_SCALING_FACTOR = 'text-scaling-factor';
const HIGH_CONTRAST_THEME = 'HighContrast';
function ATIndicator() {
this._init.apply(this, arguments);
}
ATIndicator.prototype = {
__proto__: PanelMenu.SystemStatusButton.prototype,
const ATIndicator = new Lang.Class({
Name: 'ATIndicator',
Extends: PanelMenu.SystemStatusButton,
_init: function() {
PanelMenu.SystemStatusButton.prototype._init.call(this, 'preferences-desktop-accessibility', null);
this.parent('preferences-desktop-accessibility', null);
let highContrast = this._buildHCItem();
this.menu.addMenuItem(highContrast);
@ -172,5 +168,4 @@ ATIndicator.prototype = {
});
return widget;
}
};
Signals.addSignalMethods(ATIndicator.prototype);
});

View File

@ -23,15 +23,12 @@ const ConnectionState = {
CONNECTING: 3
}
function Indicator() {
this._init.apply(this, arguments);
}
Indicator.prototype = {
__proto__: PanelMenu.SystemStatusButton.prototype,
const Indicator = new Lang.Class({
Name: 'BTIndicator',
Extends: PanelMenu.SystemStatusButton,
_init: function() {
PanelMenu.SystemStatusButton.prototype._init.call(this, 'bluetooth-disabled', null);
this.parent('bluetooth-disabled', null);
GLib.spawn_command_line_sync ('pkill -f "^bluetooth-applet$"');
this._applet = new GnomeBluetoothApplet.Applet();
@ -335,17 +332,14 @@ Indicator.prototype = {
_cancelRequest: function() {
this._source.destroy();
}
}
});
function Source() {
this._init.apply(this, arguments);
}
Source.prototype = {
__proto__: MessageTray.Source.prototype,
const Source = new Lang.Class({
Name: 'BluetoothSource',
Extends: MessageTray.Source,
_init: function() {
MessageTray.Source.prototype._init.call(this, _("Bluetooth"));
this.parent(_("Bluetooth"));
this._setSummaryIcon(this.createNotificationIcon());
},
@ -359,7 +353,7 @@ Source.prototype = {
}
}));
MessageTray.Source.prototype.notify.call(this, notification);
this.parent(notification);
},
createNotificationIcon: function() {
@ -367,21 +361,17 @@ Source.prototype = {
icon_type: St.IconType.SYMBOLIC,
icon_size: this.ICON_SIZE });
}
}
});
function AuthNotification() {
this._init.apply(this, arguments);
}
AuthNotification.prototype = {
__proto__: MessageTray.Notification.prototype,
const AuthNotification = new Lang.Class({
Name: 'AuthNotification',
Extends: MessageTray.Notification,
_init: function(source, applet, device_path, name, long_name, uuid) {
MessageTray.Notification.prototype._init.call(this,
source,
_("Bluetooth"),
_("Authorization request from %s").format(name),
{ customContent: true });
this.parent(source,
_("Bluetooth"),
_("Authorization request from %s").format(name),
{ customContent: true });
this.setResident(true);
this._applet = applet;
@ -407,21 +397,17 @@ AuthNotification.prototype = {
this.destroy();
}));
}
}
});
function ConfirmNotification() {
this._init.apply(this, arguments);
}
ConfirmNotification.prototype = {
__proto__: MessageTray.Notification.prototype,
const ConfirmNotification = new Lang.Class({
Name: 'ConfirmNotification',
Extends: MessageTray.Notification,
_init: function(source, applet, device_path, name, long_name, pin) {
MessageTray.Notification.prototype._init.call(this,
source,
_("Bluetooth"),
_("Pairing confirmation for %s").format(name),
{ customContent: true });
this.parent(source,
_("Bluetooth"),
_("Pairing confirmation for %s").format(name),
{ customContent: true });
this.setResident(true);
this._applet = applet;
@ -440,21 +426,17 @@ ConfirmNotification.prototype = {
this.destroy();
}));
}
}
});
function PinNotification() {
this._init.apply(this, arguments);
}
PinNotification.prototype = {
__proto__: MessageTray.Notification.prototype,
const PinNotification = new Lang.Class({
Name: 'PinNotification',
Extends: MessageTray.Notification,
_init: function(source, applet, device_path, name, long_name, numeric) {
MessageTray.Notification.prototype._init.call(this,
source,
_("Bluetooth"),
_("Pairing request for %s").format(name),
{ customContent: true });
this.parent(source,
_("Bluetooth"),
_("Pairing request for %s").format(name),
{ customContent: true });
this.setResident(true);
this._applet = applet;
@ -503,7 +485,7 @@ PinNotification.prototype = {
},
grabFocus: function(lockTray) {
MessageTray.Notification.prototype.grabFocus.call(this, lockTray);
this.parent(lockTray);
global.stage.set_key_focus(this._entry);
}
}
});

View File

@ -14,15 +14,12 @@ const PopupMenu = imports.ui.popupMenu;
const PanelMenu = imports.ui.panelMenu;
const Util = imports.misc.util;
function LayoutMenuItem() {
this._init.apply(this, arguments);
}
LayoutMenuItem.prototype = {
__proto__: PopupMenu.PopupBaseMenuItem.prototype,
const LayoutMenuItem = new Lang.Class({
Name: 'LayoutMenuItem',
Extends: PopupMenu.PopupBaseMenuItem,
_init: function(config, id, indicator, long_name) {
PopupMenu.PopupBaseMenuItem.prototype._init.call(this);
this.parent();
this._config = config;
this._id = id;
@ -33,20 +30,18 @@ LayoutMenuItem.prototype = {
},
activate: function(event) {
PopupMenu.PopupBaseMenuItem.prototype.activate.call(this);
this.parent(event);
this._config.lock_group(this._id);
}
};
});
function XKBIndicator() {
this._init.call(this);
}
XKBIndicator.prototype = {
__proto__: PanelMenu.Button.prototype,
const XKBIndicator = new Lang.Class({
Name: 'XKBIndicator',
Extends: PanelMenu.Button,
_init: function() {
PanelMenu.Button.prototype._init.call(this, St.Align.START);
this.parent(0.0);
this._container = new Shell.GenericContainer();
this._container.connect('get-preferred-width', Lang.bind(this, this._containerGetPreferredWidth));
@ -221,4 +216,4 @@ XKBIndicator.prototype = {
for (let i = 0; i < this._labelActors.length; i++)
this._labelActors[i].allocate_align_fill(box, 0.5, 0, false, false, flags);
}
};
});

View File

@ -97,15 +97,12 @@ function ssidToLabel(ssid) {
return label;
}
function NMNetworkMenuItem() {
this._init.apply(this, arguments);
}
NMNetworkMenuItem.prototype = {
__proto__: PopupMenu.PopupBaseMenuItem.prototype,
const NMNetworkMenuItem = new Lang.Class({
Name: 'NMNetworkMenuItem',
Extends: PopupMenu.PopupBaseMenuItem,
_init: function(accessPoints, title, params) {
PopupMenu.PopupBaseMenuItem.prototype._init.call(this, params);
this.parent(params);
accessPoints = sortAccessPoints(accessPoints);
this.bestAP = accessPoints[0];
@ -184,21 +181,18 @@ NMNetworkMenuItem.prototype = {
apObj.updateId = 0;
}
PopupMenu.PopupBaseMenuItem.prototype.destroy.call(this);
this.parent();
}
};
});
function NMWiredSectionTitleMenuItem() {
this._init.apply(this, arguments);
}
NMWiredSectionTitleMenuItem.prototype = {
__proto__: PopupMenu.PopupSwitchMenuItem.prototype,
const NMWiredSectionTitleMenuItem = new Lang.Class({
Name: 'NMWiredSectionTitleMenuItem',
Extends: PopupMenu.PopupSwitchMenuItem,
_init: function(label, params) {
params = params || { };
params.style_class = 'popup-subtitle-menu-item';
PopupMenu.PopupSwitchMenuItem.prototype._init.call(this, label, false, params);
this.parent(label, false, params);
},
updateForDevice: function(device) {
@ -211,7 +205,7 @@ NMWiredSectionTitleMenuItem.prototype = {
},
activate: function(event) {
PopupMenu.PopupSwitchMenuItem.prototype.activate.call(this, event);
this.parent(event);
if (!this._device) {
log('Section title activated when there is more than one device, should be non reactive');
@ -230,19 +224,16 @@ NMWiredSectionTitleMenuItem.prototype = {
else
this._device.deactivate();
}
};
});
function NMWirelessSectionTitleMenuItem() {
this._init.apply(this, arguments);
}
NMWirelessSectionTitleMenuItem.prototype = {
__proto__: PopupMenu.PopupSwitchMenuItem.prototype,
const NMWirelessSectionTitleMenuItem = new Lang.Class({
Name: 'NMWirelessSectionTitleMenuItem',
Extends: PopupMenu.PopupSwitchMenuItem,
_init: function(client, property, title, params) {
params = params || { };
params.style_class = 'popup-subtitle-menu-item';
PopupMenu.PopupSwitchMenuItem.prototype._init.call(this, title, false, params);
this.parent(title, false, params);
this._client = client;
this._property = property + '_enabled';
@ -268,7 +259,7 @@ NMWirelessSectionTitleMenuItem.prototype = {
},
activate: function(event) {
PopupMenu.PopupSwitchMenuItem.prototype.activate.call(this, event);
this.parent(event);
this._client[this._setEnabledFunc](this._switch.state);
},
@ -285,13 +276,12 @@ NMWirelessSectionTitleMenuItem.prototype = {
this.emit('enabled-changed', enabled);
}
};
});
function NMDevice() {
throw new TypeError('Instantanting abstract class NMDevice');
}
const NMDevice = new Lang.Class({
Name: 'NMDevice',
Abstract: true,
NMDevice.prototype = {
_init: function(client, device, connections) {
this.device = device;
if (device) {
@ -673,26 +663,23 @@ NMDevice.prototype = {
return out;
}
};
});
Signals.addSignalMethods(NMDevice.prototype);
function NMDeviceWired() {
this._init.apply(this, arguments);
}
NMDeviceWired.prototype = {
__proto__: NMDevice.prototype,
const NMDeviceWired = new Lang.Class({
Name: 'NMDeviceWired',
Extends: NMDevice,
_init: function(client, device, connections) {
this._autoConnectionName = _("Auto Ethernet");
this.category = NMConnectionCategory.WIRED;
NMDevice.prototype._init.call(this, client, device, connections);
this.parent(client, device, connections);
},
_createSection: function() {
NMDevice.prototype._createSection.call(this);
this.parent();
// if we have only one connection (normal or automatic)
// we hide the connection list, and use the switch to control
@ -717,14 +704,11 @@ NMDeviceWired.prototype = {
}));
return connection;
}
};
});
function NMDeviceModem() {
this._init.apply(this, arguments);
}
NMDeviceModem.prototype = {
__proto__: NMDevice.prototype,
const NMDeviceModem = new Lang.Class({
Name: 'NMDeviceModem',
Extends: NMDevice,
_init: function(client, device, connections) {
let is_wwan = false;
@ -773,7 +757,7 @@ NMDeviceModem.prototype = {
}));
}
NMDevice.prototype._init.call(this, client, device, connections);
this.parent(client, device, connections);
},
setEnabled: function(enabled) {
@ -786,7 +770,7 @@ NMDeviceModem.prototype = {
this.statusItem.setStatus(this.getStatusLabel());
}
NMDevice.prototype.setEnabled.call(this, enabled);
this.parent(enabled);
},
get connected() {
@ -803,7 +787,7 @@ NMDeviceModem.prototype = {
this._signalQualityId = 0;
}
NMDevice.prototype.destroy.call(this);
this.parent();
},
_getSignalIcon: function() {
@ -824,13 +808,13 @@ NMDeviceModem.prototype = {
this.section.addMenuItem(this._operatorItem);
}
NMDevice.prototype._createSection.call(this);
this.parent();
},
_clearSection: function() {
this._operatorItem = null;
NMDevice.prototype._clearSection.call(this);
this.parent();
},
_createAutomaticConnection: function() {
@ -840,14 +824,11 @@ NMDeviceModem.prototype = {
'connect-3g', this.device.get_path()]);
return null;
}
};
});
function NMDeviceBluetooth() {
this._init.apply(this, arguments);
}
NMDeviceBluetooth.prototype = {
__proto__: NMDevice.prototype,
const NMDeviceBluetooth = new Lang.Class({
Name: 'NMDeviceBluetooth',
Extends: NMDevice,
_init: function(client, device, connections) {
this._autoConnectionName = this._makeConnectionName(device);
@ -855,7 +836,7 @@ NMDeviceBluetooth.prototype = {
this.category = NMConnectionCategory.WWAN;
NMDevice.prototype._init.call(this, client, device, connections);
this.parent(client, device, connections);
},
_createAutomaticConnection: function() {
@ -885,23 +866,20 @@ NMDeviceBluetooth.prototype = {
this._clearSection();
this._createSection();
}
};
});
// Not a real device, but I save a lot code this way
function NMDeviceVPN() {
this._init.apply(this, arguments);
}
NMDeviceVPN.prototype = {
__proto__: NMDevice.prototype,
const NMDeviceVPN = new Lang.Class({
Name: 'NMDeviceVPN',
Extends: NMDevice,
_init: function(client) {
// Disable autoconnections
this._autoConnectionName = null;
this.category = NMConnectionCategory.VPN;
NMDevice.prototype._init.call(this, client, null, [ ]);
this.parent(client, null, [ ]);
},
connectionValid: function(connection) {
@ -917,7 +895,7 @@ NMDeviceVPN.prototype = {
},
setActiveConnection: function(activeConnection) {
NMDevice.prototype.setActiveConnection.call(this, activeConnection);
this.parent(activeConnection);
this.emit('active-connection-changed');
},
@ -934,14 +912,11 @@ NMDeviceVPN.prototype = {
getStatusLabel: function() {
return null;
}
};
});
function NMDeviceWireless() {
this._init.apply(this, arguments);
}
NMDeviceWireless.prototype = {
__proto__: NMDevice.prototype,
const NMDeviceWireless = new Lang.Class({
Name: 'NMDeviceWireless',
Extends: NMDevice,
_init: function(client, device, connections) {
this.category = NMConnectionCategory.WIRELESS;
@ -1013,7 +988,7 @@ NMDeviceWireless.prototype = {
this._apAddedId = device.connect('access-point-added', Lang.bind(this, this._accessPointAdded));
this._apRemovedId = device.connect('access-point-removed', Lang.bind(this, this._accessPointRemoved));
NMDevice.prototype._init.call(this, client, device, validConnections);
this.parent(client, device, validConnections);
},
destroy: function() {
@ -1033,7 +1008,7 @@ NMDeviceWireless.prototype = {
this._apRemovedId = 0;
}
NMDevice.prototype.destroy.call(this);
this.parent();
},
setEnabled: function(enabled) {
@ -1347,7 +1322,7 @@ NMDeviceWireless.prototype = {
},
_clearSection: function() {
NMDevice.prototype._clearSection.call(this);
this.parent();
for (let i = 0; i < this._networks.length; i++)
this._networks[i].item = null;
@ -1555,16 +1530,14 @@ NMDeviceWireless.prototype = {
this._createNetworkItem(apObj, j + activeOffset);
}
},
};
});
function NMApplet() {
this._init.apply(this, arguments);
}
NMApplet.prototype = {
__proto__: PanelMenu.SystemStatusButton.prototype,
const NMApplet = new Lang.Class({
Name: 'NMApplet',
Extends: PanelMenu.SystemStatusButton,
_init: function() {
PanelMenu.SystemStatusButton.prototype._init.call(this, 'network-error');
this.parent('network-error', null);
this._client = NMClient.Client.new();
@ -2130,17 +2103,14 @@ NMApplet.prototype = {
this._mobileUpdateId = 0;
}
}
};
});
function NMMessageTraySource() {
this._init();
}
NMMessageTraySource.prototype = {
__proto__: MessageTray.Source.prototype,
const NMMessageTraySource = new Lang.Class({
Name: 'NMMessageTraySource',
Extends: MessageTray.Source,
_init: function() {
MessageTray.Source.prototype._init.call(this, _("Network Manager"));
this.parent(_("Network Manager"));
let icon = new St.Icon({ icon_name: 'network-transmit-receive',
icon_type: St.IconType.SYMBOLIC,
@ -2148,4 +2118,4 @@ NMMessageTraySource.prototype = {
});
this._setSummaryIcon(icon);
}
};
});

View File

@ -52,15 +52,13 @@ const PowerManagerInterface = <interface name="org.gnome.SettingsDaemon.Power">
const PowerManagerProxy = Gio.DBusProxy.makeProxyWrapper(PowerManagerInterface);
function Indicator() {
this._init.apply(this, arguments);
}
Indicator.prototype = {
__proto__: PanelMenu.SystemStatusButton.prototype,
const Indicator = new Lang.Class({
Name: 'PowerIndicator',
Extends: PanelMenu.SystemStatusButton,
_init: function() {
PanelMenu.SystemStatusButton.prototype._init.call(this, 'battery-missing');
this.parent('battery-missing', null);
this._proxy = new PowerManagerProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH);
this._deviceItems = [ ];
@ -163,17 +161,14 @@ Indicator.prototype = {
this._readPrimaryDevice();
this._readOtherDevices();
}
};
});
function DeviceItem() {
this._init.apply(this, arguments);
}
DeviceItem.prototype = {
__proto__: PopupMenu.PopupBaseMenuItem.prototype,
const DeviceItem = new Lang.Class({
Name: 'DeviceItem',
Extends: PopupMenu.PopupBaseMenuItem,
_init: function(device) {
PopupMenu.PopupBaseMenuItem.prototype._init.call(this, { reactive: false });
this.parent({ reactive: false });
let [device_id, device_type, icon, percentage, state, time] = device;
@ -220,4 +215,4 @@ DeviceItem.prototype = {
return _("Unknown");
}
}
}
});

View File

@ -17,15 +17,12 @@ const VOLUME_ADJUSTMENT_STEP = 0.05; /* Volume adjustment step in % */
const VOLUME_NOTIFY_ID = 1;
function Indicator() {
this._init.apply(this, arguments);
}
Indicator.prototype = {
__proto__: PanelMenu.SystemStatusButton.prototype,
const Indicator = new Lang.Class({
Name: 'VolumeIndicator',
Extends: PanelMenu.SystemStatusButton,
_init: function() {
PanelMenu.SystemStatusButton.prototype._init.call(this, 'audio-volume-muted', null);
this.parent('audio-volume-muted', null);
this._control = new Gvc.MixerControl({ name: 'GNOME Shell Volume Control' });
this._control.connect('state-changed', Lang.bind(this, this._onControlStateChanged));
@ -214,4 +211,4 @@ Indicator.prototype = {
if (property == '_output' && !this._output.is_muted)
this.setIcon(this._volumeToIcon(this._output.volume));
}
};
});

View File

@ -23,11 +23,9 @@ const STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
'ibus-ui-gtk': 'input-method'
};
function StatusIconDispatcher() {
this._init();
}
const StatusIconDispatcher = new Lang.Class({
Name: 'StatusIconDispatcher',
StatusIconDispatcher.prototype = {
_init: function() {
this._traymanager = new Shell.TrayManager();
this._traymanager.connect('tray-icon-added', Lang.bind(this, this._onTrayIconAdded));
@ -61,5 +59,5 @@ StatusIconDispatcher.prototype = {
else
this.emit('message-icon-removed', icon);
}
};
});
Signals.addSignalMethods(StatusIconDispatcher.prototype);

View File

@ -72,11 +72,9 @@ function makeMessageFromTplEvent(event) {
};
}
function Client() {
this._init();
};
const Client = new Lang.Class({
Name: 'Client',
Client.prototype = {
_init : function() {
// channel path -> ChatSource
this._chatSources = {};
@ -479,17 +477,14 @@ Client.prototype = {
return this._accountSource;
}
};
});
function ChatSource(account, conn, channel, contact, client) {
this._init(account, conn, channel, contact, client);
}
ChatSource.prototype = {
__proto__: MessageTray.Source.prototype,
const ChatSource = new Lang.Class({
Name: 'ChatSource',
Extends: MessageTray.Source,
_init: function(account, conn, channel, contact, client) {
MessageTray.Source.prototype._init.call(this, contact.get_alias());
this.parent(contact.get_alias());
this.isChat = true;
@ -697,7 +692,7 @@ ChatSource.prototype = {
},
notify: function() {
MessageTray.Source.prototype.notify.call(this, this._notification);
this.parent(this._notification);
},
respond: function(text) {
@ -798,17 +793,14 @@ ChatSource.prototype = {
this._shouldAck = false;
}
};
});
function ChatNotification(source) {
this._init(source);
}
ChatNotification.prototype = {
__proto__: MessageTray.Notification.prototype,
const ChatNotification = new Lang.Class({
Name: 'ChatNotification',
Extends: MessageTray.Notification,
_init: function(source) {
MessageTray.Notification.prototype._init.call(this, source, source.title, null, { customContent: true });
this.parent(source, source.title, null, { customContent: true });
this.setResident(true);
this._responseEntry = new St.Entry({ style_class: 'chat-response',
@ -1091,17 +1083,14 @@ ChatNotification.prototype = {
this.source.setChatState(Tp.ChannelChatState.ACTIVE);
}
}
};
});
function ApproverSource(dispatchOp, text, gicon) {
this._init(dispatchOp, text, gicon);
}
ApproverSource.prototype = {
__proto__: MessageTray.Source.prototype,
const ApproverSource = new Lang.Class({
Name: 'ApproverSource',
Extends: MessageTray.Source,
_init: function(dispatchOp, text, gicon) {
MessageTray.Source.prototype._init.call(this, text);
this.parent(text);
this._gicon = gicon;
this._setSummaryIcon(this.createNotificationIcon());
@ -1122,7 +1111,7 @@ ApproverSource.prototype = {
this._invalidId = 0;
}
MessageTray.Source.prototype.destroy.call(this);
this.parent();
},
createNotificationIcon: function() {
@ -1130,23 +1119,19 @@ ApproverSource.prototype = {
icon_type: St.IconType.FULLCOLOR,
icon_size: this.ICON_SIZE });
}
}
});
function RoomInviteNotification(source, dispatchOp, channel, inviter) {
this._init(source, dispatchOp, channel, inviter);
}
RoomInviteNotification.prototype = {
__proto__: MessageTray.Notification.prototype,
const RoomInviteNotification = new Lang.Class({
Name: 'RoomInviteNotification',
Extends: MessageTray.Notification,
_init: function(source, dispatchOp, channel, inviter) {
MessageTray.Notification.prototype._init.call(this,
source,
/* translators: argument is a room name like
* room@jabber.org for example. */
_("Invitation to %s").format(channel.get_identifier()),
null,
{ customContent: true });
this.parent(source,
/* translators: argument is a room name like
* room@jabber.org for example. */
_("Invitation to %s").format(channel.get_identifier()),
null,
{ customContent: true });
this.setResident(true);
/* translators: first argument is the name of a contact and the second
@ -1173,15 +1158,12 @@ RoomInviteNotification.prototype = {
this.destroy();
}));
}
};
});
// Audio Video
function AudioVideoNotification(source, dispatchOp, channel, contact, isVideo) {
this._init(source, dispatchOp, channel, contact, isVideo);
}
AudioVideoNotification.prototype = {
__proto__: MessageTray.Notification.prototype,
const AudioVideoNotification = new Lang.Class({
Name: 'AudioVideoNotification',
Extends: MessageTray.Notification,
_init: function(source, dispatchOp, channel, contact, isVideo) {
let title = '';
@ -1193,11 +1175,7 @@ AudioVideoNotification.prototype = {
/* translators: argument is a contact name like Alice for example. */
title = _("Call from %s").format(contact.get_alias());
MessageTray.Notification.prototype._init.call(this,
source,
title,
null,
{ customContent: true });
this.parent(this, source, title, null, { customContent: true });
this.setResident(true);
this.addButton('reject', _("Reject"));
@ -1220,28 +1198,25 @@ AudioVideoNotification.prototype = {
this.destroy();
}));
}
};
});
// File Transfer
function FileTransferNotification(source, dispatchOp, channel, contact) {
this._init(source, dispatchOp, channel, contact);
}
FileTransferNotification.prototype = {
__proto__: MessageTray.Notification.prototype,
const FileTransferNotification = new Lang.Class({
Name: 'FileTransferNotification',
Extends: MessageTray.Notification,
_init: function(source, dispatchOp, channel, contact) {
MessageTray.Notification.prototype._init.call(this,
source,
/* To translators: The first parameter is
* the contact's alias and the second one is the
* file name. The string will be something
* like: "Alice is sending you test.ogg"
*/
_("%s is sending you %s").format(contact.get_alias(),
channel.get_filename()),
null,
{ customContent: true });
this.parent(this,
source,
/* To translators: The first parameter is
* the contact's alias and the second one is the
* file name. The string will be something
* like: "Alice is sending you test.ogg"
*/
_("%s is sending you %s").format(contact.get_alias(),
channel.get_filename()),
null,
{ customContent: true });
this.setResident(true);
this.addButton('decline', _("Decline"));
@ -1263,18 +1238,15 @@ FileTransferNotification.prototype = {
this.destroy();
}));
}
};
});
// A notification source that can embed multiple notifications
function MultiNotificationSource(title, icon) {
this._init(title, icon);
}
MultiNotificationSource.prototype = {
__proto__: MessageTray.Source.prototype,
const MultiNotificationSource = new Lang.Class({
Name: 'MultiNotificationSource',
Extends: MessageTray.Source,
_init: function(title, icon) {
MessageTray.Source.prototype._init.call(this, title);
this.parent(title);
this._icon = icon;
this._setSummaryIcon(this.createNotificationIcon());
@ -1282,7 +1254,7 @@ MultiNotificationSource.prototype = {
},
notify: function(notification) {
MessageTray.Source.prototype.notify.call(this, notification);
this.parent(notification);
this._nbNotifications += 1;
@ -1300,21 +1272,18 @@ MultiNotificationSource.prototype = {
icon_type: St.IconType.FULLCOLOR,
icon_size: this.ICON_SIZE });
}
};
});
// Subscription request
function SubscriptionRequestNotification(source, contact) {
this._init(source, contact);
}
SubscriptionRequestNotification.prototype = {
__proto__: MessageTray.Notification.prototype,
const SubscriptionRequestNotification = new Lang.Class({
Name: 'SubscriptionRequestNotification',
Extends: MessageTray.Notification,
_init: function(source, contact) {
MessageTray.Notification.prototype._init.call(this, source,
/* To translators: The parameter is the contact's alias */
_("%s would like permission to see when you are online").format(contact.get_alias()),
null, { customContent: true });
this.parent(this, source,
/* To translators: The parameter is the contact's alias */
_("%s would like permission to see when you are online").format(contact.get_alias()),
null, { customContent: true });
this._contact = contact;
this._connection = contact.get_connection();
@ -1388,7 +1357,7 @@ SubscriptionRequestNotification.prototype = {
this._invalidatedId = 0;
}
MessageTray.Notification.prototype.destroy.call(this);
this.parent();
},
_subscriptionStatesChangedCb: function(contact, subscribe, publish, msg) {
@ -1397,12 +1366,7 @@ SubscriptionRequestNotification.prototype = {
if (publish != Tp.SubscriptionState.ASK)
this.destroy();
}
};
function AccountNotification(source, account, connectionError) {
this._init(source, account, connectionError);
}
});
// Messages from empathy/libempathy/empathy-utils.c
// create_errors_to_message_hash()
@ -1457,15 +1421,16 @@ _connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.CERT_INSECURE)]
_connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.CERT_LIMIT_EXCEEDED)]
= _("The length of the server certificate, or the depth of the server certificate chain, exceed the limits imposed by the cryptography library");
AccountNotification.prototype = {
__proto__: MessageTray.Notification.prototype,
const AccountNotification = new Lang.Class({
Name: 'AccountNotification',
Extends: MessageTray.Notification,
_init: function(source, account, connectionError) {
MessageTray.Notification.prototype._init.call(this, source,
/* translators: argument is the account name, like
* name@jabber.org for example. */
_("Connection to %s failed").format(account.get_display_name()),
null, { customContent: true });
this.parent(source,
/* translators: argument is the account name, like
* name@jabber.org for example. */
_("Connection to %s failed").format(account.get_display_name()),
null, { customContent: true });
this._label = new St.Label();
this.addActor(this._label);
@ -1541,6 +1506,6 @@ AccountNotification.prototype = {
this._connectionStatusId = 0;
}
MessageTray.Notification.prototype.destroy.call(this);
this.parent();
}
};
});

View File

@ -202,11 +202,9 @@ function registerSpecialPropertySplitter(name, splitFunction, parameters) {
// time updates; even better is to pay attention to the vertical
// vblank and sync to that when possible.)
//
function ClutterFrameTicker() {
this._init();
}
const ClutterFrameTicker = new Lang.Class({
Name: 'ClutterFrameTicker',
ClutterFrameTicker.prototype = {
FRAME_RATE : 60,
_init : function() {
@ -261,6 +259,6 @@ ClutterFrameTicker.prototype = {
this._startTime = -1;
global.end_work();
}
};
});
Signals.addSignalMethods(ClutterFrameTicker.prototype);

View File

@ -40,15 +40,12 @@ const IMStatus = {
// Copyright (C) 2008,2009 Red Hat, Inc.
function IMStatusItem(label, iconName) {
this._init(label, iconName);
}
IMStatusItem.prototype = {
__proto__: PopupMenu.PopupBaseMenuItem.prototype,
const IMStatusItem = new Lang.Class({
Name: 'IMStatusItem',
Extends: PopupMenu.PopupBaseMenuItem,
_init: function(label, iconName) {
PopupMenu.PopupBaseMenuItem.prototype._init.call(this);
this.parent();
this.actor.add_style_class_name('status-chooser-status-item');
@ -61,19 +58,15 @@ IMStatusItem.prototype = {
this.label = new St.Label({ text: label });
this.addActor(this.label);
}
};
});
function IMUserNameItem() {
this._init();
}
IMUserNameItem.prototype = {
__proto__: PopupMenu.PopupBaseMenuItem.prototype,
const IMUserNameItem = new Lang.Class({
Name: 'IMUserNameItem',
Extends: PopupMenu.PopupBaseMenuItem,
_init: function() {
PopupMenu.PopupBaseMenuItem.prototype._init.call(this,
{ reactive: false,
style_class: 'status-chooser-user-name' });
this.parent({ reactive: false,
style_class: 'status-chooser-user-name' });
this._wrapper = new Shell.GenericContainer();
this._wrapper.connect('get-preferred-width',
@ -102,19 +95,15 @@ IMUserNameItem.prototype = {
_wrapperAllocate: function(actor, box, flags) {
this.label.allocate(box, flags);
}
};
});
function IMStatusChooserItem() {
this._init();
}
IMStatusChooserItem.prototype = {
__proto__: PopupMenu.PopupBaseMenuItem.prototype,
const IMStatusChooserItem = new Lang.Class({
Name: 'IMStatusChooserItem',
Extends: PopupMenu.PopupBaseMenuItem,
_init: function() {
PopupMenu.PopupBaseMenuItem.prototype._init.call (this,
{ reactive: false,
style_class: 'status-chooser' });
this.parent({ reactive: false,
style_class: 'status-chooser' });
this._iconBin = new St.Button({ style_class: 'status-chooser-user-icon' });
this.addActor(this._iconBin);
@ -220,7 +209,7 @@ IMStatusChooserItem.prototype = {
this._userChangedId = 0;
}
PopupMenu.PopupBaseMenuItem.prototype.destroy.call(this);
this.parent();
},
// Override getColumnWidths()/setColumnWidths() to make the item
@ -422,18 +411,16 @@ IMStatusChooserItem.prototype = {
this._expectedPresence = newPresence;
this._accountMgr.set_all_requested_presences(newPresence, status, msg);
}
};
});
function UserMenuButton() {
this._init();
}
UserMenuButton.prototype = {
__proto__: PanelMenu.Button.prototype,
const UserMenuButton = new Lang.Class({
Name: 'UserMenuButton',
Extends: PanelMenu.Button,
_init: function() {
PanelMenu.Button.prototype._init.call(this, 0.0);
this.parent(0.0);
let box = new St.BoxLayout({ name: 'panelUserMenu' });
this.actor.add_actor(box);
@ -736,4 +723,4 @@ UserMenuButton.prototype = {
this._session.ShutdownRemote();
}
}
};
});

View File

@ -15,11 +15,9 @@ const SearchDisplay = imports.ui.searchDisplay;
const ShellEntry = imports.ui.shellEntry;
const Tweener = imports.ui.tweener;
function BaseTab(titleActor, pageActor, name, a11yIcon) {
this._init(titleActor, pageActor, name, a11yIcon);
}
const BaseTab = new Lang.Class({
Name: 'BaseTab',
BaseTab.prototype = {
_init: function(titleActor, pageActor, name, a11yIcon) {
this.title = titleActor;
this.page = new St.Bin({ child: pageActor,
@ -75,16 +73,13 @@ BaseTab.prototype = {
_activate: function() {
this.emit('activated');
}
};
});
Signals.addSignalMethods(BaseTab.prototype);
function ViewTab(id, label, pageActor, a11yIcon) {
this._init(id, label, pageActor, a11yIcon);
}
ViewTab.prototype = {
__proto__: BaseTab.prototype,
const ViewTab = new Lang.Class({
Name: 'ViewTab',
Extends: BaseTab,
_init: function(id, label, pageActor, a11yIcon) {
this.id = id;
@ -93,17 +88,14 @@ ViewTab.prototype = {
style_class: 'view-tab-title' });
titleActor.connect('clicked', Lang.bind(this, this._activate));
BaseTab.prototype._init.call(this, titleActor, pageActor, label, a11yIcon);
this.parent(titleActor, pageActor, label, a11yIcon);
}
};
});
function SearchTab() {
this._init();
}
SearchTab.prototype = {
__proto__: BaseTab.prototype,
const SearchTab = new Lang.Class({
Name: 'SearchTab',
Extends: BaseTab,
_init: function() {
this.active = false;
@ -136,11 +128,7 @@ SearchTab.prototype = {
this._iconClickedId = 0;
this._searchResults = new SearchDisplay.SearchResults(this._searchSystem, this._openSearchSystem);
BaseTab.prototype._init.call(this,
this._entry,
this._searchResults.actor,
_("Search"),
'edit-find');
this.parent(this._entry, this._searchResults.actor, _("Search"), 'edit-find');
this._text.connect('text-changed', Lang.bind(this, this._onTextChanged));
this._text.connect('key-press-event', Lang.bind(this, function (o, e) {
@ -166,7 +154,7 @@ SearchTab.prototype = {
},
hide: function() {
BaseTab.prototype.hide.call(this);
this.parent();
// Leave the entry focused when it doesn't have any text;
// when replacing a selected search term, Clutter emits
@ -310,14 +298,12 @@ SearchTab.prototype = {
return false;
}
};
});
function ViewSelector() {
this._init();
}
const ViewSelector = new Lang.Class({
Name: 'ViewSelector',
ViewSelector.prototype = {
_init : function() {
this.actor = new St.BoxLayout({ name: 'viewSelector',
vertical: true });
@ -577,5 +563,5 @@ ViewSelector.prototype = {
removeSearchProvider: function(provider) {
this._searchTab.removeSearchProvider(provider);
}
};
});
Signals.addSignalMethods(ViewSelector.prototype);

View File

@ -6,11 +6,9 @@ const Shell = imports.gi.Shell;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
function WindowAttentionHandler() {
this._init();
}
const WindowAttentionHandler = new Lang.Class({
Name: 'WindowAttentionHandler',
WindowAttentionHandler.prototype = {
_init : function() {
this._tracker = Shell.WindowTracker.get_default();
global.display.connect('window-demands-attention', Lang.bind(this, this._onWindowDemandsAttention));
@ -43,17 +41,14 @@ WindowAttentionHandler.prototype = {
notification.update(title, banner);
})));
}
};
});
function Source(app, window) {
this._init(app, window);
}
Source.prototype = {
__proto__ : MessageTray.Source.prototype,
const Source = new Lang.Class({
Name: 'WindowAttentionSource',
Extends: MessageTray.Source,
_init: function(app, window) {
MessageTray.Source.prototype._init.call(this, app.get_name());
this.parent(app.get_name());
this._window = window;
this._app = app;
this._setSummaryIcon(this.createNotificationIcon());
@ -81,4 +76,4 @@ Source.prototype = {
Main.activateWindow(this._window);
this.destroy();
}
};
});

View File

@ -31,11 +31,9 @@ function getTopInvisibleBorder(metaWindow) {
return outerRect.y - inputRect.y;
}
function WindowDimmer(actor) {
this._init(actor);
}
const WindowDimmer = new Lang.Class({
Name: 'WindowDimmer',
WindowDimmer.prototype = {
_init: function(actor) {
if (Clutter.feature_available(Clutter.FeatureFlags.SHADERS_GLSL)) {
this._effect = new Clutter.ShaderEffect({ shader_type: Clutter.ShaderType.FRAGMENT_SHADER });
@ -75,7 +73,7 @@ WindowDimmer.prototype = {
},
_dimFraction: 0.0
};
});
function getWindowDimmer(actor) {
if (!actor._windowDimmer)
@ -84,11 +82,9 @@ function getWindowDimmer(actor) {
return actor._windowDimmer;
}
function WindowManager() {
this._init();
}
const WindowManager = new Lang.Class({
Name: 'WindowManager',
WindowManager.prototype = {
_init : function() {
this._shellwm = global.window_manager;
@ -627,4 +623,4 @@ WindowManager.prototype = {
if (!Main.overview.visible)
this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.DOWN, indexToActivate);
}
};
});

View File

@ -56,11 +56,13 @@ function _clamp(value, min, max) {
}
function ScaledPoint(x, y, scaleX, scaleY) {
[this.x, this.y, this.scaleX, this.scaleY] = arguments;
}
const ScaledPoint = new Lang.Class({
Name: 'ScaledPoint',
_init: function(x, y, scaleX, scaleY) {
[this.x, this.y, this.scaleX, this.scaleY] = arguments;
},
ScaledPoint.prototype = {
getPosition : function() {
return [this.x, this.y];
},
@ -86,14 +88,12 @@ ScaledPoint.prototype = {
return [_interpolate(this.scaleX, other.scaleX, step),
_interpolate(this.scaleY, other.scaleY, step)];
}
};
});
function WindowClone(realWindow) {
this._init(realWindow);
}
const WindowClone = new Lang.Class({
Name: 'WindowClone',
WindowClone.prototype = {
_init : function(realWindow) {
this.realWindow = realWindow;
this.metaWindow = realWindow.meta_window;
@ -418,7 +418,7 @@ WindowClone.prototype = {
this.emit('drag-end');
}
};
});
Signals.addSignalMethods(WindowClone.prototype);
@ -427,11 +427,9 @@ Signals.addSignalMethods(WindowClone.prototype);
* @parentActor: The actor which will be the parent of all overlay items
* such as app icon and window caption
*/
function WindowOverlay(windowClone, parentActor) {
this._init(windowClone, parentActor);
}
const WindowOverlay = new Lang.Class({
Name: 'WindowOverlay',
WindowOverlay.prototype = {
_init : function(windowClone, parentActor) {
let metaWindow = windowClone.metaWindow;
@ -642,7 +640,7 @@ WindowOverlay.prototype = {
this._parentActor.queue_relayout();
}
};
});
Signals.addSignalMethods(WindowOverlay.prototype);
const WindowPositionFlags = {
@ -653,11 +651,9 @@ const WindowPositionFlags = {
/**
* @metaWorkspace: a #Meta.Workspace, or null
*/
function Workspace(metaWorkspace, monitorIndex) {
this._init(metaWorkspace, monitorIndex);
}
const Workspace = new Lang.Class({
Name: 'Workspace',
Workspace.prototype = {
_init : function(metaWorkspace, monitorIndex) {
// When dragging a window, we use this slot for reserve space.
this._reservedSlot = null;
@ -1518,6 +1514,6 @@ Workspace.prototype = {
return false;
}
};
});
Signals.addSignalMethods(Workspace.prototype);

View File

@ -15,11 +15,9 @@ const DISPLAY_TIMEOUT = 600;
const UP = -1;
const DOWN = 1;
function WorkspaceSwitcherPopup() {
this._init();
}
const WorkspaceSwitcherPopup = new Lang.Class({
Name: 'WorkspaceSwitcherPopup',
WorkspaceSwitcherPopup.prototype = {
_init : function() {
this.actor = new St.Group({ reactive: true,
x: 0,
@ -158,4 +156,4 @@ WorkspaceSwitcherPopup.prototype = {
onCompleteScope: this
});
}
};
});

View File

@ -25,11 +25,9 @@ const SLIDE_ANIMATION_TIME = 0.2;
// placeholder exactly.
const WORKSPACE_CUT_SIZE = 10;
function WindowClone(realWindow) {
this._init(realWindow);
}
const WindowClone = new Lang.Class({
Name: 'WindowClone',
WindowClone.prototype = {
_init : function(realWindow) {
this.actor = new Clutter.Clone({ source: realWindow.get_texture(),
reactive: true });
@ -126,7 +124,7 @@ WindowClone.prototype = {
this.emit('drag-end');
}
};
});
Signals.addSignalMethods(WindowClone.prototype);
@ -144,11 +142,9 @@ const ThumbnailState = {
/**
* @metaWorkspace: a #Meta.Workspace
*/
function WorkspaceThumbnail(metaWorkspace) {
this._init(metaWorkspace);
}
const WorkspaceThumbnail = new Lang.Class({
Name: 'WorkspaceThumbnail',
WorkspaceThumbnail.prototype = {
_init : function(metaWorkspace) {
this.metaWorkspace = metaWorkspace;
this.monitorIndex = Main.layoutManager.primaryIndex;
@ -469,16 +465,14 @@ WorkspaceThumbnail.prototype = {
return false;
}
};
});
Signals.addSignalMethods(WorkspaceThumbnail.prototype);
function ThumbnailsBox() {
this._init();
}
const ThumbnailsBox = new Lang.Class({
Name: 'ThumbnailsBox',
ThumbnailsBox.prototype = {
_init: function() {
this.actor = new Shell.GenericContainer({ style_class: 'workspace-thumbnails',
request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT });
@ -1028,4 +1022,4 @@ ThumbnailsBox.prototype = {
onCompleteScope: this
});
}
};
});

View File

@ -23,11 +23,9 @@ const MAX_WORKSPACES = 16;
const CONTROLS_POP_IN_TIME = 0.1;
function WorkspacesView(workspaces) {
this._init(workspaces);
}
const WorkspacesView = new Lang.Class({
Name: 'WorkspacesView',
WorkspacesView.prototype = {
_init: function(workspaces) {
this.actor = new St.Group({ style_class: 'workspaces-view' });
@ -452,15 +450,13 @@ WorkspacesView.prototype = {
_getWorkspaceIndexToRemove: function() {
return global.screen.get_active_workspace_index();
}
};
});
Signals.addSignalMethods(WorkspacesView.prototype);
function WorkspacesDisplay() {
this._init();
}
const WorkspacesDisplay = new Lang.Class({
Name: 'WorkspacesDisplay',
WorkspacesDisplay.prototype = {
_init: function() {
this.actor = new Shell.GenericContainer();
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
@ -852,5 +848,5 @@ WorkspacesDisplay.prototype = {
break;
}
}
};
});
Signals.addSignalMethods(WorkspacesDisplay.prototype);

View File

@ -6,11 +6,9 @@ const Shell = imports.gi.Shell;
const Signals = imports.signals;
const DND = imports.ui.dnd;
function XdndHandler() {
this._init();
}
const XdndHandler = new Lang.Class({
Name: 'XdndHandler',
XdndHandler.prototype = {
_init: function() {
// Used to display a clone of the cursor window when the
// window group is hidden (like it happens in the overview)
@ -125,6 +123,6 @@ XdndHandler.prototype = {
pickedActor = pickedActor.get_parent();
}
}
}
});
Signals.addSignalMethods(XdndHandler.prototype);

View File

@ -121,9 +121,18 @@ shell_public_headers_h = \
shell-wm.h \
shell-xfixes-cursor.h
shell_private_sources = \
gactionmuxer.h \
gactionmuxer.c \
gactionobservable.h \
gactionobservable.c \
gactionobserver.h \
gactionobserver.c
libgnome_shell_la_SOURCES = \
$(shell_built_sources) \
$(shell_public_headers_h) \
$(shell_private_sources) \
shell-app-private.h \
shell-app-system-private.h \
shell-embedded-window-private.h \
@ -157,10 +166,12 @@ libgnome_shell_la_SOURCES = \
shell-util.c \
shell-window-tracker.c \
shell-wm.c \
shell-xfixes-cursor.c
shell-xfixes-cursor.c \
$(NULL)
libgnome_shell_la_gir_sources = \
$(filter-out %-private.h $(shell_recorder_non_gir_sources), $(shell_public_headers_h) $(libgnome_shell_la_SOURCES))
$(filter-out %-private.h $(shell_private_sources), $(shell_public_headers_h) $(libgnome_shell_la_SOURCES))
gnome_shell_real_SOURCES = \
main.c
@ -175,12 +186,16 @@ shell_recorder_sources = \
shell-recorder.h
# Custom element is an internal detail
shell_recorder_non_gir_sources = \
shell-recorder-src.c \
shell-recorder-src.h
if BUILD_RECORDER
libgnome_shell_la_SOURCES += $(shell_recorder_sources) $(shell_recorder_non_gir_sources)
libgnome_shell_la_SOURCES += $(shell_recorder_sources)
shell_recorder_private_sources = \
shell-recorder-src.c \
shell-recorder-src.h \
$(NULL)
shell_private_sources += $(shell_recorder_private_sources)
noinst_PROGRAMS += test-recorder
@ -188,7 +203,7 @@ test_recorder_CPPFLAGS = $(TEST_SHELL_RECORDER_CFLAGS)
test_recorder_LDADD = $(TEST_SHELL_RECORDER_LIBS)
test_recorder_SOURCES = \
$(shell_recorder_sources) $(shell_recorder_non_gir_sources) \
$(shell_recorder_sources) $(shell_recorder_private_sources) \
test-recorder.c
endif BUILD_RECORDER

533
src/gactionmuxer.c Normal file
View File

@ -0,0 +1,533 @@
/*
* Copyright © 2011 Canonical Limited
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the licence, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Author: Ryan Lortie <desrt@desrt.ca>
*/
#include "config.h"
#include "gactionmuxer.h"
#include "gactionobservable.h"
#include "gactionobserver.h"
#include <clutter/clutter.h>
#include <string.h>
/*
* SECTION:gactionmuxer
* @short_description: Aggregate and monitor several action groups
*
* #GActionMuxer is a #GActionGroup and #GActionObservable that is
* capable of containing other #GActionGroup instances.
*
* The typical use is aggregating all of the actions applicable to a
* particular context into a single action group, with namespacing.
*
* Consider the case of two action groups -- one containing actions
* applicable to an entire application (such as 'quit') and one
* containing actions applicable to a particular window in the
* application (such as 'fullscreen').
*
* In this case, each of these action groups could be added to a
* #GActionMuxer with the prefixes "app" and "win", respectively. This
* would expose the actions as "app.quit" and "win.fullscreen" on the
* #GActionGroup interface presented by the #GActionMuxer.
*
* Activations and state change requests on the #GActionMuxer are wired
* through to the underlying action group in the expected way.
*
* This class is typically only used at the site of "consumption" of
* actions (eg: when displaying a menu that contains many actions on
* different objects).
*/
static void g_action_muxer_group_iface_init (GActionGroupInterface *iface);
static void g_action_muxer_observable_iface_init (GActionObservableInterface *iface);
typedef GObjectClass GActionMuxerClass;
struct _GActionMuxer
{
GObject parent_instance;
GHashTable *actions;
GHashTable *groups;
};
G_DEFINE_TYPE_WITH_CODE (GActionMuxer, g_action_muxer, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, g_action_muxer_group_iface_init)
G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_OBSERVABLE, g_action_muxer_observable_iface_init))
typedef struct
{
GActionMuxer *muxer;
GSList *watchers;
gchar *fullname;
} Action;
typedef struct
{
GActionMuxer *muxer;
GActionGroup *group;
gchar *prefix;
gulong handler_ids[4];
} Group;
static gchar **
g_action_muxer_list_actions (GActionGroup *action_group)
{
GActionMuxer *muxer = G_ACTION_MUXER (action_group);
return (gchar **) muxer->groups;
}
static Group *
g_action_muxer_find_group (GActionMuxer *muxer,
const gchar **name)
{
const gchar *dot;
gchar *prefix;
Group *group;
dot = strchr (*name, '.');
if (!dot)
return NULL;
prefix = g_strndup (*name, dot - *name);
group = g_hash_table_lookup (muxer->groups, prefix);
g_free (prefix);
*name = dot + 1;
return group;
}
static Action *
g_action_muxer_lookup_action (GActionMuxer *muxer,
const gchar *prefix,
const gchar *action_name,
gchar **fullname)
{
Action *action;
*fullname = g_strconcat (prefix, ".", action_name, NULL);
action = g_hash_table_lookup (muxer->actions, *fullname);
return action;
}
static void
g_action_muxer_action_enabled_changed (GActionGroup *action_group,
const gchar *action_name,
gboolean enabled,
gpointer user_data)
{
Group *group = user_data;
gchar *fullname;
Action *action;
GSList *node;
action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
for (node = action ? action->watchers : NULL; node; node = node->next)
g_action_observer_action_enabled_changed (node->data, G_ACTION_OBSERVABLE (group->muxer), fullname, enabled);
g_action_group_action_enabled_changed (G_ACTION_GROUP (group->muxer), fullname, enabled);
g_free (fullname);
}
static void
g_action_muxer_action_state_changed (GActionGroup *action_group,
const gchar *action_name,
GVariant *state,
gpointer user_data)
{
Group *group = user_data;
gchar *fullname;
Action *action;
GSList *node;
action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
for (node = action ? action->watchers : NULL; node; node = node->next)
g_action_observer_action_state_changed (node->data, G_ACTION_OBSERVABLE (group->muxer), fullname, state);
g_action_group_action_state_changed (G_ACTION_GROUP (group->muxer), fullname, state);
g_free (fullname);
}
static void
g_action_muxer_action_added (GActionGroup *action_group,
const gchar *action_name,
gpointer user_data)
{
const GVariantType *parameter_type;
Group *group = user_data;
gboolean enabled;
GVariant *state;
if (g_action_group_query_action (group->group, action_name, &enabled, &parameter_type, NULL, NULL, &state))
{
gchar *fullname;
Action *action;
GSList *node;
action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
for (node = action ? action->watchers : NULL; node; node = node->next)
g_action_observer_action_added (node->data,
G_ACTION_OBSERVABLE (group->muxer),
fullname, parameter_type, enabled, state);
g_action_group_action_added (G_ACTION_GROUP (group->muxer), fullname);
if (state)
g_variant_unref (state);
g_free (fullname);
}
}
static void
g_action_muxer_action_removed (GActionGroup *action_group,
const gchar *action_name,
gpointer user_data)
{
Group *group = user_data;
gchar *fullname;
Action *action;
GSList *node;
action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
for (node = action ? action->watchers : NULL; node; node = node->next)
g_action_observer_action_removed (node->data, G_ACTION_OBSERVABLE (group->muxer), fullname);
g_action_group_action_removed (G_ACTION_GROUP (group->muxer), fullname);
g_free (fullname);
}
static gboolean
g_action_muxer_query_action (GActionGroup *action_group,
const gchar *action_name,
gboolean *enabled,
const GVariantType **parameter_type,
const GVariantType **state_type,
GVariant **state_hint,
GVariant **state)
{
GActionMuxer *muxer = G_ACTION_MUXER (action_group);
Group *group;
group = g_action_muxer_find_group (muxer, &action_name);
if (!group)
return FALSE;
return g_action_group_query_action (group->group, action_name, enabled,
parameter_type, state_type, state_hint, state);
}
static GVariant *
get_platform_data (void)
{
gchar time[32];
GVariantBuilder *builder;
GVariant *result;
g_snprintf (time, 32, "_TIME%d", clutter_get_current_event_time ());
builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (builder, "{sv}", "desktop-startup-id",
g_variant_new_string (time));
result = g_variant_builder_end (builder);
g_variant_builder_unref (builder);
return result;
}
static void
g_action_muxer_activate_action (GActionGroup *action_group,
const gchar *action_name,
GVariant *parameter)
{
GActionMuxer *muxer = G_ACTION_MUXER (action_group);
Group *group;
group = g_action_muxer_find_group (muxer, &action_name);
if (group)
{
if (G_IS_REMOTE_ACTION_GROUP (group->group))
g_remote_action_group_activate_action_full (G_REMOTE_ACTION_GROUP (group->group),
action_name,
parameter,
get_platform_data ());
else
g_action_group_activate_action (group->group, action_name, parameter);
}
}
static void
g_action_muxer_change_action_state (GActionGroup *action_group,
const gchar *action_name,
GVariant *state)
{
GActionMuxer *muxer = G_ACTION_MUXER (action_group);
Group *group;
group = g_action_muxer_find_group (muxer, &action_name);
if (group)
{
if (G_IS_REMOTE_ACTION_GROUP (group->group))
g_remote_action_group_change_action_state_full (G_REMOTE_ACTION_GROUP (group->group),
action_name,
state,
get_platform_data ());
else
g_action_group_change_action_state (group->group, action_name, state);
}
}
static void
g_action_muxer_unregister_internal (Action *action,
gpointer observer)
{
GActionMuxer *muxer = action->muxer;
GSList **ptr;
for (ptr = &action->watchers; *ptr; ptr = &(*ptr)->next)
if ((*ptr)->data == observer)
{
*ptr = g_slist_remove (*ptr, observer);
if (action->watchers == NULL)
{
g_hash_table_remove (muxer->actions, action->fullname);
g_free (action->fullname);
g_slice_free (Action, action);
g_object_unref (muxer);
}
break;
}
}
static void
g_action_muxer_weak_notify (gpointer data,
GObject *where_the_object_was)
{
Action *action = data;
g_action_muxer_unregister_internal (action, where_the_object_was);
}
static void
g_action_muxer_register_observer (GActionObservable *observable,
const gchar *name,
GActionObserver *observer)
{
GActionMuxer *muxer = G_ACTION_MUXER (observable);
Action *action;
action = g_hash_table_lookup (muxer->actions, name);
if (action == NULL)
{
action = g_slice_new (Action);
action->muxer = g_object_ref (muxer);
action->fullname = g_strdup (name);
action->watchers = NULL;
g_hash_table_insert (muxer->actions, action->fullname, action);
}
action->watchers = g_slist_prepend (action->watchers, observer);
g_object_weak_ref (G_OBJECT (observer), g_action_muxer_weak_notify, action);
}
static void
g_action_muxer_unregister_observer (GActionObservable *observable,
const gchar *name,
GActionObserver *observer)
{
GActionMuxer *muxer = G_ACTION_MUXER (observable);
Action *action;
action = g_hash_table_lookup (muxer->actions, name);
g_object_weak_unref (G_OBJECT (observer), g_action_muxer_weak_notify, action);
g_action_muxer_unregister_internal (action, observer);
}
static void
g_action_muxer_free_group (gpointer data)
{
Group *group = data;
g_object_unref (group->group);
g_free (group->prefix);
g_slice_free (Group, group);
}
static void
g_action_muxer_finalize (GObject *object)
{
GActionMuxer *muxer = G_ACTION_MUXER (object);
g_assert_cmpint (g_hash_table_size (muxer->actions), ==, 0);
g_hash_table_unref (muxer->actions);
g_hash_table_unref (muxer->groups);
G_OBJECT_CLASS (g_action_muxer_parent_class)
->finalize (object);
}
static void
g_action_muxer_init (GActionMuxer *muxer)
{
muxer->actions = g_hash_table_new (g_str_hash, g_str_equal);
muxer->groups = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_action_muxer_free_group);
}
static void
g_action_muxer_observable_iface_init (GActionObservableInterface *iface)
{
iface->register_observer = g_action_muxer_register_observer;
iface->unregister_observer = g_action_muxer_unregister_observer;
}
static void
g_action_muxer_group_iface_init (GActionGroupInterface *iface)
{
iface->list_actions = g_action_muxer_list_actions;
iface->query_action = g_action_muxer_query_action;
iface->activate_action = g_action_muxer_activate_action;
iface->change_action_state = g_action_muxer_change_action_state;
}
static void
g_action_muxer_class_init (GObjectClass *class)
{
class->finalize = g_action_muxer_finalize;
}
/*
* g_action_muxer_insert:
* @muxer: a #GActionMuxer
* @prefix: the prefix string for the action group
* @action_group: a #GActionGroup
*
* Adds the actions in @action_group to the list of actions provided by
* @muxer. @prefix is prefixed to each action name, such that for each
* action <varname>x</varname> in @action_group, there is an equivalent
* action @prefix<literal>.</literal><varname>x</varname> in @muxer.
*
* For example, if @prefix is "<literal>app</literal>" and @action_group
* contains an action called "<literal>quit</literal>", then @muxer will
* now contain an action called "<literal>app.quit</literal>".
*
* If any #GActionObservers are registered for actions in the group,
* "action_added" notifications will be emitted, as appropriate.
*
* @prefix must not contain a dot ('.').
*/
void
g_action_muxer_insert (GActionMuxer *muxer,
const gchar *prefix,
GActionGroup *action_group)
{
gchar **actions;
Group *group;
gint i;
/* TODO: diff instead of ripout and replace */
g_action_muxer_remove (muxer, prefix);
group = g_slice_new (Group);
group->muxer = muxer;
group->group = g_object_ref (action_group);
group->prefix = g_strdup (prefix);
g_hash_table_insert (muxer->groups, group->prefix, group);
actions = g_action_group_list_actions (group->group);
for (i = 0; actions[i]; i++)
g_action_muxer_action_added (group->group, actions[i], group);
g_strfreev (actions);
group->handler_ids[0] = g_signal_connect (group->group, "action-added",
G_CALLBACK (g_action_muxer_action_added), group);
group->handler_ids[1] = g_signal_connect (group->group, "action-removed",
G_CALLBACK (g_action_muxer_action_removed), group);
group->handler_ids[2] = g_signal_connect (group->group, "action-enabled-changed",
G_CALLBACK (g_action_muxer_action_enabled_changed), group);
group->handler_ids[3] = g_signal_connect (group->group, "action-state-changed",
G_CALLBACK (g_action_muxer_action_state_changed), group);
}
/*
* g_action_muxer_remove:
* @muxer: a #GActionMuxer
* @prefix: the prefix of the action group to remove
*
* Removes a #GActionGroup from the #GActionMuxer.
*
* If any #GActionObservers are registered for actions in the group,
* "action_removed" notifications will be emitted, as appropriate.
*/
void
g_action_muxer_remove (GActionMuxer *muxer,
const gchar *prefix)
{
Group *group;
group = g_hash_table_lookup (muxer->groups, prefix);
if (group != NULL)
{
gchar **actions;
gint i;
g_hash_table_steal (muxer->groups, prefix);
actions = g_action_group_list_actions (group->group);
for (i = 0; actions[i]; i++)
g_action_muxer_action_removed (group->group, actions[i], group);
g_strfreev (actions);
/* 'for loop' or 'four loop'? */
for (i = 0; i < 4; i++)
g_signal_handler_disconnect (group->group, group->handler_ids[i]);
g_action_muxer_free_group (group);
}
}
/*
* g_action_muxer_new:
*
* Creates a new #GActionMuxer.
*/
GActionMuxer *
g_action_muxer_new (void)
{
return g_object_new (G_TYPE_ACTION_MUXER, NULL);
}

53
src/gactionmuxer.h Normal file
View File

@ -0,0 +1,53 @@
/*
* Copyright © 2011 Canonical Limited
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the licence, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Author: Ryan Lortie <desrt@desrt.ca>
*/
#ifndef __G_ACTION_MUXER_H__
#define __G_ACTION_MUXER_H__
#include <gio/gio.h>
G_BEGIN_DECLS
#define G_TYPE_ACTION_MUXER (g_action_muxer_get_type ())
#define G_ACTION_MUXER(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
G_TYPE_ACTION_MUXER, GActionMuxer))
#define G_IS_ACTION_MUXER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
G_TYPE_ACTION_MUXER))
typedef struct _GActionMuxer GActionMuxer;
G_GNUC_INTERNAL
GType g_action_muxer_get_type (void);
G_GNUC_INTERNAL
GActionMuxer * g_action_muxer_new (void);
G_GNUC_INTERNAL
void g_action_muxer_insert (GActionMuxer *muxer,
const gchar *prefix,
GActionGroup *group);
G_GNUC_INTERNAL
void g_action_muxer_remove (GActionMuxer *muxer,
const gchar *prefix);
G_END_DECLS
#endif /* __G_ACTION_MUXER_H__ */

80
src/gactionobservable.c Normal file
View File

@ -0,0 +1,80 @@
/*
* Copyright © 2011 Canonical Limited
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* licence or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
* USA.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
*/
#include "config.h"
#include "gactionobservable.h"
G_DEFINE_INTERFACE (GActionObservable, g_action_observable, G_TYPE_OBJECT)
/*
* SECTION:gactionobserable
* @short_description: an interface implemented by objects that report
* changes to actions
*/
void
g_action_observable_default_init (GActionObservableInterface *iface)
{
}
/*
* g_action_observable_register_observer:
* @observable: a #GActionObservable
* @action_name: the name of the action
* @observer: the #GActionObserver to which the events will be reported
*
* Registers @observer as being interested in changes to @action_name on
* @observable.
*/
void
g_action_observable_register_observer (GActionObservable *observable,
const gchar *action_name,
GActionObserver *observer)
{
g_return_if_fail (G_IS_ACTION_OBSERVABLE (observable));
G_ACTION_OBSERVABLE_GET_IFACE (observable)
->register_observer (observable, action_name, observer);
}
/*
* g_action_observable_unregister_observer:
* @observable: a #GActionObservable
* @action_name: the name of the action
* @observer: the #GActionObserver to which the events will be reported
*
* Removes the registration of @observer as being interested in changes
* to @action_name on @observable.
*
* If the observer was registered multiple times, it must be
* unregistered an equal number of times.
*/
void
g_action_observable_unregister_observer (GActionObservable *observable,
const gchar *action_name,
GActionObserver *observer)
{
g_return_if_fail (G_IS_ACTION_OBSERVABLE (observable));
G_ACTION_OBSERVABLE_GET_IFACE (observable)
->unregister_observer (observable, action_name, observer);
}

64
src/gactionobservable.h Normal file
View File

@ -0,0 +1,64 @@
/*
* Copyright © 2011 Canonical Limited
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* licence or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
* USA.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
*/
#ifndef __G_ACTION_OBSERVABLE_H__
#define __G_ACTION_OBSERVABLE_H__
#include "gactionobserver.h"
G_BEGIN_DECLS
#define G_TYPE_ACTION_OBSERVABLE (g_action_observable_get_type ())
#define G_ACTION_OBSERVABLE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
G_TYPE_ACTION_OBSERVABLE, GActionObservable))
#define G_IS_ACTION_OBSERVABLE(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
G_TYPE_ACTION_OBSERVABLE))
#define G_ACTION_OBSERVABLE_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), \
G_TYPE_ACTION_OBSERVABLE, GActionObservableInterface))
typedef struct _GActionObservableInterface GActionObservableInterface;
struct _GActionObservableInterface
{
GTypeInterface g_iface;
void (* register_observer) (GActionObservable *observable,
const gchar *action_name,
GActionObserver *observer);
void (* unregister_observer) (GActionObservable *observable,
const gchar *action_name,
GActionObserver *observer);
};
G_GNUC_INTERNAL
GType g_action_observable_get_type (void);
G_GNUC_INTERNAL
void g_action_observable_register_observer (GActionObservable *observable,
const gchar *action_name,
GActionObserver *observer);
G_GNUC_INTERNAL
void g_action_observable_unregister_observer (GActionObservable *observable,
const gchar *action_name,
GActionObserver *observer);
G_END_DECLS
#endif /* __G_ACTION_OBSERVABLE_H__ */

161
src/gactionobserver.c Normal file
View File

@ -0,0 +1,161 @@
/*
* Copyright © 2011 Canonical Limited
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* licence or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
* USA.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
*/
#include "config.h"
#include "gactionobserver.h"
G_DEFINE_INTERFACE (GActionObserver, g_action_observer, G_TYPE_OBJECT)
/**
* SECTION:gactionobserver
* @short_description: an interface implemented by objects that are
* interested in monitoring actions for changes
*
* GActionObserver is a simple interface allowing objects that wish to
* be notified of changes to actions to be notified of those changes.
*
* It is also possible to monitor changes to action groups using
* #GObject signals, but there are a number of reasons that this
* approach could become problematic:
*
* - there are four separate signals that must be manually connected
* and disconnected
*
* - when a large number of different observers wish to monitor a
* (usually disjoint) set of actions within the same action group,
* there is only one way to avoid having all notifications delivered
* to all observers: signal detail. In order to use signal detail,
* each action name must be quarked, which is not always practical.
*
* - even if quarking is acceptable, #GObject signal details are
* implemented by scanning a linked list, so there is no real
* decrease in complexity
*/
void
g_action_observer_default_init (GActionObserverInterface *class)
{
}
/*
* g_action_observer_action_added:
* @observer: a #GActionObserver
* @observable: the source of the event
* @action_name: the name of the action
* @enabled: %TRUE if the action is now enabled
* @parameter_type: the parameter type for action invocations, or %NULL
* if no parameter is required
* @state: the current state of the action, or %NULL if the action is
* stateless
*
* This function is called when an action that the observer is
* registered to receive events for is added.
*
* This function should only be called by objects with which the
* observer has explicitly registered itself to receive events.
*/
void
g_action_observer_action_added (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
const GVariantType *parameter_type,
gboolean enabled,
GVariant *state)
{
g_return_if_fail (G_IS_ACTION_OBSERVER (observer));
G_ACTION_OBSERVER_GET_IFACE (observer)
->action_added (observer, observable, action_name, parameter_type, enabled, state);
}
/*
* g_action_observer_action_enabled_changed:
* @observer: a #GActionObserver
* @observable: the source of the event
* @action_name: the name of the action
* @enabled: %TRUE if the action is now enabled
*
* This function is called when an action that the observer is
* registered to receive events for becomes enabled or disabled.
*
* This function should only be called by objects with which the
* observer has explicitly registered itself to receive events.
*/
void
g_action_observer_action_enabled_changed (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
gboolean enabled)
{
g_return_if_fail (G_IS_ACTION_OBSERVER (observer));
G_ACTION_OBSERVER_GET_IFACE (observer)
->action_enabled_changed (observer, observable, action_name, enabled);
}
/*
* g_action_observer_action_state_changed:
* @observer: a #GActionObserver
* @observable: the source of the event
* @action_name: the name of the action
* @state: the new state of the action
*
* This function is called when an action that the observer is
* registered to receive events for changes its state.
*
* This function should only be called by objects with which the
* observer has explicitly registered itself to receive events.
*/
void
g_action_observer_action_state_changed (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
GVariant *state)
{
g_return_if_fail (G_IS_ACTION_OBSERVER (observer));
G_ACTION_OBSERVER_GET_IFACE (observer)
->action_state_changed (observer, observable, action_name, state);
}
/*
* g_action_observer_action_removed:
* @observer: a #GActionObserver
* @observable: the source of the event
* @action_name: the name of the action
*
* This function is called when an action that the observer is
* registered to receive events for is removed.
*
* This function should only be called by objects with which the
* observer has explicitly registered itself to receive events.
*/
void
g_action_observer_action_removed (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name)
{
g_return_if_fail (G_IS_ACTION_OBSERVER (observer));
G_ACTION_OBSERVER_GET_IFACE (observer)
->action_removed (observer, observable, action_name);
}

90
src/gactionobserver.h Normal file
View File

@ -0,0 +1,90 @@
/*
* Copyright © 2011 Canonical Limited
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* licence or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
* USA.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
*/
#ifndef __G_ACTION_OBSERVER_H__
#define __G_ACTION_OBSERVER_H__
#include <gio/gio.h>
G_BEGIN_DECLS
#define G_TYPE_ACTION_OBSERVER (g_action_observer_get_type ())
#define G_ACTION_OBSERVER(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
G_TYPE_ACTION_OBSERVER, GActionObserver))
#define G_IS_ACTION_OBSERVER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
G_TYPE_ACTION_OBSERVER))
#define G_ACTION_OBSERVER_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), \
G_TYPE_ACTION_OBSERVER, GActionObserverInterface))
typedef struct _GActionObserverInterface GActionObserverInterface;
typedef struct _GActionObservable GActionObservable;
typedef struct _GActionObserver GActionObserver;
struct _GActionObserverInterface
{
GTypeInterface g_iface;
void (* action_added) (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
const GVariantType *parameter_type,
gboolean enabled,
GVariant *state);
void (* action_enabled_changed) (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
gboolean enabled);
void (* action_state_changed) (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
GVariant *state);
void (* action_removed) (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name);
};
G_GNUC_INTERNAL
GType g_action_observer_get_type (void);
G_GNUC_INTERNAL
void g_action_observer_action_added (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
const GVariantType *parameter_type,
gboolean enabled,
GVariant *state);
G_GNUC_INTERNAL
void g_action_observer_action_enabled_changed (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
gboolean enabled);
G_GNUC_INTERNAL
void g_action_observer_action_state_changed (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
GVariant *state);
G_GNUC_INTERNAL
void g_action_observer_action_removed (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name);
G_END_DECLS
#endif /* __G_ACTION_OBSERVER_H__ */

View File

@ -15,6 +15,7 @@
#include "shell-app-system-private.h"
#include "shell-window-tracker-private.h"
#include "st.h"
#include "gactionmuxer.h"
typedef enum {
MATCH_NONE,
@ -37,6 +38,15 @@ typedef struct {
/* Whether or not we need to resort the windows; this is done on demand */
gboolean window_sort_stale : 1;
/* See GApplication documentation */
gint name_watcher_id;
gchar *dbus_name;
GDBusProxy *app_proxy;
GActionGroup *remote_actions;
GMenuModel *remote_menu;
GActionMuxer *muxer;
GCancellable *dbus_cancellable;
} ShellAppRunningState;
/**
@ -72,11 +82,13 @@ struct _ShellApp
char *casefolded_exec;
};
G_DEFINE_TYPE (ShellApp, shell_app, G_TYPE_OBJECT);
enum {
PROP_0,
PROP_STATE
PROP_STATE,
PROP_ID,
PROP_DBUS_ID,
PROP_ACTION_GROUP,
PROP_MENU
};
enum {
@ -88,6 +100,15 @@ static guint shell_app_signals[LAST_SIGNAL] = { 0 };
static void create_running_state (ShellApp *app);
static void unref_running_state (ShellAppRunningState *state);
static void on_dbus_name_appeared (GDBusConnection *bus,
const gchar *name,
const gchar *name_owner,
gpointer user_data);
static void on_dbus_name_disappeared (GDBusConnection *bus,
const gchar *name,
gpointer user_data);
G_DEFINE_TYPE (ShellApp, shell_app, G_TYPE_OBJECT)
static void
shell_app_get_property (GObject *gobject,
@ -102,6 +123,20 @@ shell_app_get_property (GObject *gobject,
case PROP_STATE:
g_value_set_enum (value, app->state);
break;
case PROP_ID:
g_value_set_string (value, shell_app_get_id (app));
break;
case PROP_DBUS_ID:
g_value_set_string (value, shell_app_get_dbus_id (app));
break;
case PROP_ACTION_GROUP:
if (app->running_state)
g_value_set_object (value, app->running_state->muxer);
break;
case PROP_MENU:
if (app->running_state)
g_value_set_object (value, app->running_state->remote_menu);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
@ -151,6 +186,15 @@ window_backed_app_get_icon (ShellApp *app,
return actor;
}
const char *
shell_app_get_dbus_id (ShellApp *app)
{
if (app->running_state)
return app->running_state->dbus_name;
else
return NULL;
}
/**
* shell_app_create_icon_texture:
*
@ -513,6 +557,31 @@ shell_app_activate_window (ShellApp *app,
}
}
void
shell_app_update_window_actions (ShellApp *app, MetaWindow *window)
{
const char *object_path;
object_path = meta_window_get_dbus_object_path (window);
if (object_path != NULL)
{
GActionGroup *actions;
actions = g_object_get_data (G_OBJECT (window), "actions");
if (actions == NULL)
{
actions = G_ACTION_GROUP (g_dbus_action_group_get (g_dbus_proxy_get_connection (app->running_state->app_proxy),
meta_window_get_dbus_unique_name (window),
object_path));
g_object_set_data_full (G_OBJECT (window), "actions", actions, g_object_unref);
}
g_action_muxer_insert (app->running_state->muxer, "win", actions);
g_object_notify (G_OBJECT (app), "action-group");
}
}
/**
* shell_app_activate:
* @app: a #ShellApp
@ -903,6 +972,34 @@ shell_app_on_ws_switch (MetaScreen *screen,
g_signal_emit (app, shell_app_signals[WINDOWS_CHANGED], 0);
}
static void
on_dbus_application_id_changed (MetaWindow *window,
GParamSpec *pspec,
gpointer user_data)
{
const char *appid;
ShellApp *app = SHELL_APP (user_data);
/* Ignore changes in the appid after it's set, shouldn't happen */
if (app->running_state->dbus_name != NULL)
return;
appid = meta_window_get_dbus_application_id (window);
if (!appid)
return;
g_assert (app->running_state != NULL);
app->running_state->dbus_name = g_strdup (appid);
app->running_state->name_watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
appid,
G_BUS_NAME_WATCHER_FLAGS_NONE,
on_dbus_name_appeared,
on_dbus_name_disappeared,
g_object_ref (app),
g_object_unref);
}
void
_shell_app_add_window (ShellApp *app,
MetaWindow *window)
@ -923,6 +1020,9 @@ _shell_app_add_window (ShellApp *app,
if (app->state != SHELL_APP_STATE_STARTING)
shell_app_state_transition (app, SHELL_APP_STATE_RUNNING);
g_signal_connect (window, "notify::dbus-application-id", G_CALLBACK(on_dbus_application_id_changed), app);
on_dbus_application_id_changed (window, NULL, app);
g_object_thaw_notify (G_OBJECT (app));
g_signal_emit (app, shell_app_signals[WINDOWS_CHANGED], 0);
@ -939,6 +1039,7 @@ _shell_app_remove_window (ShellApp *app,
g_signal_handlers_disconnect_by_func (window, G_CALLBACK(shell_app_on_unmanaged), app);
g_signal_handlers_disconnect_by_func (window, G_CALLBACK(shell_app_on_user_time_changed), app);
g_signal_handlers_disconnect_by_func (window, G_CALLBACK(on_dbus_application_id_changed), app);
g_object_unref (window);
app->running_state->windows = g_slist_remove (app->running_state->windows, window);
@ -948,6 +1049,134 @@ _shell_app_remove_window (ShellApp *app,
g_signal_emit (app, shell_app_signals[WINDOWS_CHANGED], 0);
}
static void
on_dbus_proxy_gotten (GObject *initable,
GAsyncResult *result,
gpointer user_data)
{
ShellApp *self = SHELL_APP (user_data);
ShellAppRunningState *state = self->running_state;
GError *error = NULL;
GVariant *menu_property;
state->app_proxy = g_dbus_proxy_new_finish (result,
&error);
if (error)
{
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
!g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD))
{
g_warning ("Unexpected error while creating application proxy: %s", error->message);
}
g_clear_error (&error);
g_clear_object (&state->dbus_cancellable);
if (state->name_watcher_id)
{
g_bus_unwatch_name (state->name_watcher_id);
state->name_watcher_id = 0;
}
g_free (state->dbus_name);
state->dbus_name = NULL;
g_object_unref (self);
return;
}
/* on to the second step, the primary action group */
state->remote_actions = (GActionGroup*)g_dbus_action_group_get (
g_dbus_proxy_get_connection (state->app_proxy),
g_dbus_proxy_get_name (state->app_proxy),
g_dbus_proxy_get_object_path (state->app_proxy));
state->muxer = g_action_muxer_new ();
g_action_muxer_insert (state->muxer, "app", state->remote_actions);
g_strfreev (g_action_group_list_actions (state->remote_actions));
g_object_notify (G_OBJECT (self), "action-group");
menu_property = g_dbus_proxy_get_cached_property (state->app_proxy, "AppMenu");
if (menu_property && g_variant_n_children (menu_property) > 0)
{
const gchar *object_path;
g_variant_get_child (menu_property, 0, "&o", &object_path);
state->remote_menu = G_MENU_MODEL (g_dbus_menu_model_get (g_dbus_proxy_get_connection (state->app_proxy),
state->dbus_name,
object_path));
g_object_notify (G_OBJECT (self), "menu");
}
}
static void
on_dbus_name_appeared (GDBusConnection *bus,
const gchar *name,
const gchar *name_owner,
gpointer user_data)
{
ShellApp *self = SHELL_APP (user_data);
ShellAppRunningState *state = self->running_state;
char *object_path;
g_assert (state != NULL);
object_path = g_strconcat ("/", name, NULL);
g_strdelimit (object_path, ".", '/');
if (!state->dbus_cancellable)
state->dbus_cancellable = g_cancellable_new ();
/* first step: the application proxy */
g_dbus_proxy_new (bus,
G_DBUS_PROXY_FLAGS_NONE,
NULL, /* interface info */
name_owner,
object_path,
"org.gtk.Application",
state->dbus_cancellable,
on_dbus_proxy_gotten,
g_object_ref (self));
g_object_notify (G_OBJECT (self), "dbus-id");
g_free (object_path);
}
static void
on_dbus_name_disappeared (GDBusConnection *bus,
const gchar *name,
gpointer user_data)
{
ShellApp *self = SHELL_APP (user_data);
ShellAppRunningState *state = self->running_state;
g_assert (state != NULL);
if (state->dbus_cancellable)
{
g_cancellable_cancel (state->dbus_cancellable);
g_clear_object (&state->dbus_cancellable);
}
g_clear_object (&state->app_proxy);
g_clear_object (&state->remote_actions);
g_clear_object (&state->remote_menu);
g_clear_object (&state->muxer);
g_free (state->dbus_name);
state->dbus_name = NULL;
g_bus_unwatch_name (state->name_watcher_id);
state->name_watcher_id = 0;
}
/**
* shell_app_get_pids:
* @app: a #ShellApp
@ -1167,13 +1396,30 @@ unref_running_state (ShellAppRunningState *state)
{
MetaScreen *screen;
g_assert (state->refcount > 0);
state->refcount--;
if (state->refcount > 0)
return;
screen = shell_global_get_screen (shell_global_get ());
g_signal_handler_disconnect (screen, state->workspace_switch_id);
if (state->dbus_cancellable)
{
g_cancellable_cancel (state->dbus_cancellable);
g_object_unref (state->dbus_cancellable);
}
g_clear_object (&state->app_proxy);
g_clear_object (&state->remote_actions);
g_clear_object (&state->remote_menu);
g_clear_object (&state->muxer);
g_free (state->dbus_name);
if (state->name_watcher_id)
g_bus_unwatch_name (state->name_watcher_id);
g_slice_free (ShellAppRunningState, state);
}
@ -1349,6 +1595,9 @@ shell_app_dispose (GObject *object)
while (app->running_state->windows)
_shell_app_remove_window (app, app->running_state->windows->data);
}
/* We should have been transitioned when we removed all of our windows */
g_assert (app->state == SHELL_APP_STATE_STOPPED);
g_assert (app->running_state == NULL);
G_OBJECT_CLASS(shell_app_parent_class)->dispose (object);
}
@ -1399,4 +1648,60 @@ shell_app_class_init(ShellAppClass *klass)
SHELL_TYPE_APP_STATE,
SHELL_APP_STATE_STOPPED,
G_PARAM_READABLE));
/**
* ShellApp:id:
*
* The id of this application (a desktop filename, or a special string
* like window:0xabcd1234)
*/
g_object_class_install_property (gobject_class,
PROP_ID,
g_param_spec_string ("id",
"Application id",
"The desktop file id of this ShellApp",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
/**
* ShellApp:dbus-id:
*
* The DBus well-known name of the application, if one can be associated
* to this ShellApp (it means that the application is using GApplication)
*/
g_object_class_install_property (gobject_class,
PROP_DBUS_ID,
g_param_spec_string ("dbus-id",
"Application DBus Id",
"The DBus well-known name of the application",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
/**
* ShellApp:action-group:
*
* The #GDBusActionGroup associated with this ShellApp, if any. See the
* documentation of #GApplication and #GActionGroup for details.
*/
g_object_class_install_property (gobject_class,
PROP_ACTION_GROUP,
g_param_spec_object ("action-group",
"Application Action Group",
"The action group exported by the remote application",
G_TYPE_ACTION_GROUP,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
/**
* ShellApp:menu:
*
* The #GMenuProxy associated with this ShellApp, if any. See the
* documentation of #GMenuModel for details.
*/
g_object_class_install_property (gobject_class,
PROP_MENU,
g_param_spec_object ("menu",
"Application Menu",
"The primary menu exported by the remote application",
G_TYPE_MENU_MODEL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
}

View File

@ -13,6 +13,7 @@ G_BEGIN_DECLS
typedef struct _ShellApp ShellApp;
typedef struct _ShellAppClass ShellAppClass;
typedef struct _ShellAppPrivate ShellAppPrivate;
typedef struct _ShellAppAction ShellAppAction;
#define SHELL_TYPE_APP (shell_app_get_type ())
#define SHELL_APP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SHELL_TYPE_APP, ShellApp))
@ -36,9 +37,12 @@ typedef enum {
GType shell_app_get_type (void) G_GNUC_CONST;
const char *shell_app_get_id (ShellApp *app);
GMenuTreeEntry *shell_app_get_tree_entry (ShellApp *app);
GDesktopAppInfo *shell_app_get_app_info (ShellApp *app);
const char *shell_app_get_dbus_id (ShellApp *app);
ClutterActor *shell_app_create_icon_texture (ShellApp *app, int size);
ClutterActor *shell_app_get_faded_icon (ShellApp *app, int size);
const char *shell_app_get_name (ShellApp *app);
@ -79,6 +83,8 @@ int shell_app_compare_by_name (ShellApp *app, ShellApp *other);
int shell_app_compare (ShellApp *app, ShellApp *other);
void shell_app_update_window_actions (ShellApp *app, MetaWindow *window);
G_END_DECLS
#endif /* __SHELL_APP_H__ */

View File

@ -413,6 +413,9 @@ update_focus_app (ShellWindowTracker *self)
new_focus_win = meta_display_get_focus_window (shell_global_get_display (shell_global_get ()));
new_focus_app = new_focus_win ? shell_window_tracker_get_window_app (self, new_focus_win) : NULL;
if (new_focus_app)
shell_app_update_window_actions (new_focus_app, new_focus_win);
set_focus_app (self, new_focus_app);
}

104
src/test-gapplication.js Executable file
View File

@ -0,0 +1,104 @@
#!/usr/bin/env gjs
const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
function do_action(action, parameter) {
print ("Action '" + action.name + "' invoked");
}
function do_action_param(action, parameter) {
print ("Action '" + action.name + "' invoked with parameter " + parameter.print(true));
}
function do_action_toggle(action) {
action.set_state(GLib.Variant.new('b', !action.state.deep_unpack()));
print ("Toggled");
}
function do_action_state_change(action) {
print ("Action '" + action.name + "' has now state " + action.state.print(true));
}
function main() {
Gtk.init(null, null);
let app = new Gtk.Application({ application_id: 'org.gnome.Shell.GtkApplicationTest' });
app.connect('activate', function() {
print ("Activated");
});
let action = new Gio.SimpleAction({ name: 'one' });
action.connect('activate', do_action);
app.add_action(action);
let action = new Gio.SimpleAction({ name: 'two' });
action.connect('activate', do_action);
app.add_action(action);
let action = new Gio.SimpleAction({ name: 'toggle', state: GLib.Variant.new('b', false) });
action.connect('activate', do_action_toggle);
action.connect('notify::state', do_action_state_change);
app.add_action(action);
let action = new Gio.SimpleAction({ name: 'disable', enabled: false });
action.set_enabled(false);
action.connect('activate', do_action);
app.add_action(action);
let action = new Gio.SimpleAction({ name: 'parameter-int', parameter_type: GLib.VariantType.new('u') });
action.connect('activate', do_action_param);
app.add_action(action);
let action = new Gio.SimpleAction({ name: 'parameter-string', parameter_type: GLib.VariantType.new('s') });
action.connect('activate', do_action_param);
app.add_action(action);
let menu = new Gio.Menu();
menu.append('An action', 'app.one');
let section = new Gio.Menu();
section.append('Another action', 'app.two');
section.append('Same as above', 'app.two');
menu.append_section(null, section);
// another section, to check separators
section = new Gio.Menu();
section.append('Checkbox', 'app.toggle');
section.append('Disabled', 'app.disable');
menu.append_section(null, section);
// empty sections or submenus should be invisible
menu.append_section('Empty section', new Gio.Menu());
menu.append_submenu('Empty submenu', new Gio.Menu());
let submenu = new Gio.Menu();
submenu.append('Open c:\\', 'app.parameter-string::c:\\');
submenu.append('Open /home', 'app.parameter-string::/home');
menu.append_submenu('Recent files', submenu);
let item = Gio.MenuItem.new('Say 42', null);
item.set_action_and_target_value('app.parameter-int', GLib.Variant.new('u', 42));
menu.append_item(item);
let item = Gio.MenuItem.new('Say 43', null);
item.set_action_and_target_value('app.parameter-int', GLib.Variant.new('u', 43));
menu.append_item(item);
app.set_app_menu(menu);
let window = null;
app.connect_after('startup', function(app) {
window = new Gtk.ApplicationWindow({ title: "Test Application", application: app });
});
app.connect('activate', function(app) {
window.present();
});
app.run(null);
}
main();