Compare commits
1 Commits
wip/loc-ap
...
wip/jstpie
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8c9aa2efd9 |
@@ -7,13 +7,6 @@ const Meta = imports.gi.Meta;
|
||||
const GnomeDesktop = imports.gi.GnomeDesktop;
|
||||
const Shell = imports.gi.Shell;
|
||||
|
||||
// We stop polling if the user is idle for more than this amount of time
|
||||
const IDLE_TIME = 1000;
|
||||
|
||||
// This file implements a reasonably efficient system for tracking the position
|
||||
// of the mouse pointer. We simply query the pointer from the X server in a loop,
|
||||
// but we turn off the polling when the user is idle.
|
||||
|
||||
let _pointerWatcher = null;
|
||||
function getPointerWatcher() {
|
||||
if (_pointerWatcher == null)
|
||||
@@ -25,9 +18,8 @@ function getPointerWatcher() {
|
||||
const PointerWatch = new Lang.Class({
|
||||
Name: 'PointerWatch',
|
||||
|
||||
_init: function(watcher, interval, callback) {
|
||||
_init: function(watcher, callback) {
|
||||
this.watcher = watcher;
|
||||
this.interval = interval;
|
||||
this.callback = callback;
|
||||
},
|
||||
|
||||
@@ -43,9 +35,9 @@ const PointerWatcher = new Lang.Class({
|
||||
Name: 'PointerWatcher',
|
||||
|
||||
_init: function() {
|
||||
this._idleMonitor = Meta.IdleMonitor.get_core();
|
||||
this._idleMonitor.add_idle_watch(IDLE_TIME, Lang.bind(this, this._onIdleMonitorBecameIdle));
|
||||
this._idle = this._idleMonitor.get_idletime() > IDLE_TIME;
|
||||
this._cursorTracker = Meta.CursorTracker.get_for_screen(global.screen);
|
||||
this._cursorTracker.connect('position-changed', Lang.bind(this, this._updatePointer));
|
||||
|
||||
this._watches = [];
|
||||
this.pointerX = null;
|
||||
this.pointerY = null;
|
||||
@@ -61,60 +53,25 @@ const PointerWatcher = new Lang.Class({
|
||||
// Set up a watch on the position of the mouse pointer. Returns a
|
||||
// PointerWatch object which has a remove() method to remove the watch.
|
||||
addWatch: function(interval, callback) {
|
||||
this._cursorTracker.enable_track_position();
|
||||
|
||||
// Avoid unreliably calling the watch for the current position
|
||||
this._updatePointer();
|
||||
|
||||
let watch = new PointerWatch(this, interval, callback);
|
||||
this._watches.push(watch);
|
||||
this._updateTimeout();
|
||||
this._watches.push(callback);
|
||||
return watch;
|
||||
},
|
||||
|
||||
_removeWatch: function(watch) {
|
||||
for (let i = 0; i < this._watches.length; i++) {
|
||||
if (this._watches[i] == watch) {
|
||||
this._cursorTracker.disable_track_position();
|
||||
this._watches.splice(i, 1);
|
||||
this._updateTimeout();
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_onIdleMonitorBecameActive: function(monitor) {
|
||||
this._idle = false;
|
||||
this._updatePointer();
|
||||
this._updateTimeout();
|
||||
},
|
||||
|
||||
_onIdleMonitorBecameIdle: function(monitor) {
|
||||
this._idle = true;
|
||||
this._idleMonitor.add_user_active_watch(Lang.bind(this, this._onIdleMonitorBecameActive));
|
||||
this._updateTimeout();
|
||||
},
|
||||
|
||||
_updateTimeout: function() {
|
||||
if (this._timeoutId) {
|
||||
Mainloop.source_remove(this._timeoutId);
|
||||
this._timeoutId = 0;
|
||||
}
|
||||
|
||||
if (this._idle || this._watches.length == 0)
|
||||
return;
|
||||
|
||||
let minInterval = this._watches[0].interval;
|
||||
for (let i = 1; i < this._watches.length; i++)
|
||||
minInterval = Math.min(this._watches[i].interval, minInterval);
|
||||
|
||||
this._timeoutId = Mainloop.timeout_add(minInterval,
|
||||
Lang.bind(this, this._onTimeout));
|
||||
GLib.Source.set_name_by_id(this._timeoutId, '[gnome-shell] this._onTimeout');
|
||||
},
|
||||
|
||||
_onTimeout: function() {
|
||||
this._updatePointer();
|
||||
return GLib.SOURCE_CONTINUE;
|
||||
},
|
||||
|
||||
_updatePointer: function() {
|
||||
let [x, y, mods] = global.get_pointer();
|
||||
if (this.pointerX == x && this.pointerY == y)
|
||||
|
@@ -137,10 +137,6 @@ const Slider = new Lang.Class({
|
||||
this._motionId = this.actor.connect('motion-event', Lang.bind(this, this._motionEvent));
|
||||
}
|
||||
|
||||
// We need to emit 'drag-begin' before moving the handle to make
|
||||
// sure that no 'value-changed' signal is emitted before this one.
|
||||
this.emit('drag-begin');
|
||||
|
||||
let absX, absY;
|
||||
[absX, absY] = event.get_coords();
|
||||
this._moveHandle(absX, absY);
|
||||
@@ -228,7 +224,6 @@ const Slider = new Lang.Class({
|
||||
let delta = key == Clutter.KEY_Right ? 0.1 : -0.1;
|
||||
this._value = Math.max(0, Math.min(this._value + delta, 1));
|
||||
this.actor.queue_repaint();
|
||||
this.emit('drag-begin');
|
||||
this.emit('value-changed', this._value);
|
||||
this.emit('drag-end');
|
||||
return Clutter.EVENT_STOP;
|
||||
|
@@ -7,17 +7,12 @@ const Lang = imports.lang;
|
||||
const Main = imports.ui.main;
|
||||
const PanelMenu = imports.ui.panelMenu;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const LOCATION_SCHEMA = 'org.gnome.system.location';
|
||||
const MAX_ACCURACY_LEVEL = 'max-accuracy-level';
|
||||
const ENABLED = 'enabled';
|
||||
|
||||
const APP_PERMISSIONS_TABLE = 'desktop';
|
||||
const APP_PERMISSIONS_ID = 'geolocation';
|
||||
|
||||
const GeoclueAccuracyLevel = {
|
||||
NONE: 0,
|
||||
COUNTRY: 1,
|
||||
@@ -51,26 +46,6 @@ var AgentIface = '<node> \
|
||||
</interface> \
|
||||
</node>';
|
||||
|
||||
var XdgAppIface = '<node> \
|
||||
<interface name="org.freedesktop.XdgApp.PermissionStore"> \
|
||||
<method name="Lookup"> \
|
||||
<arg name="table" type="s" direction="in"/> \
|
||||
<arg name="id" type="s" direction="in"/> \
|
||||
<arg name="permissions" type="a{sas}" direction="out"/> \
|
||||
<arg name="data" type="v" direction="out"/> \
|
||||
</method> \
|
||||
<method name="Set"> \
|
||||
<arg name="table" type="s" direction="in"/> \
|
||||
<arg name="create" type="b" direction="in"/> \
|
||||
<arg name="id" type="s" direction="in"/> \
|
||||
<arg name="app_permissions" type="a{sas}" direction="in"/> \
|
||||
<arg name="data" type="v" direction="in"/> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
|
||||
const PermissionStore = Gio.DBusProxy.makeProxyWrapper(XdgAppIface);
|
||||
|
||||
const Indicator = new Lang.Class({
|
||||
Name: 'LocationIndicator',
|
||||
Extends: PanelMenu.SystemIndicator,
|
||||
@@ -108,200 +83,64 @@ const Indicator = new Lang.Class({
|
||||
this._onSessionUpdated();
|
||||
this._onMaxAccuracyLevelChanged();
|
||||
this._connectToGeoclue();
|
||||
this._connectToPermissionStore();
|
||||
},
|
||||
|
||||
get MaxAccuracyLevel() {
|
||||
return this._getMaxAccuracyLevel();
|
||||
},
|
||||
|
||||
AuthorizeAppAsync: function(params, invocation) {
|
||||
let [desktop_id, reqAccuracyLevel] = params;
|
||||
log("%s is requesting location".format(desktop_id));
|
||||
|
||||
let callback = function(level, timesAllowed) {
|
||||
if (level >= GeoclueAccuracyLevel.NONE && timesAllowed > 2) {
|
||||
log("%s is in store".format(desktop_id));
|
||||
let accuracyLevel = clamp(reqAccuracyLevel, 0, level);
|
||||
this._completeAuthorizeApp(desktop_id,
|
||||
accuracyLevel,
|
||||
timesAllowed,
|
||||
invocation);
|
||||
} else {
|
||||
log("%s not in store".format(desktop_id));
|
||||
this._userAuthorizeApp(desktop_id,
|
||||
reqAccuracyLevel,
|
||||
timesAllowed,
|
||||
invocation);
|
||||
}
|
||||
}
|
||||
this._fetchPermissionFromStore(desktop_id, Lang.bind(this, callback);
|
||||
},
|
||||
|
||||
_userAuthorizeApp: function(desktopId, reqAccuracyLevel, timesAllowed, invocation) {
|
||||
// We (and geoclue) have currently no way to reliably identifying apps so
|
||||
// for now, lets just authorize all apps as long as they provide a valid
|
||||
// desktop ID. We also ensure they don't get more accuracy than global max.
|
||||
AuthorizeApp: function(desktop_id, reqAccuracyLevel) {
|
||||
var appSystem = Shell.AppSystem.get_default();
|
||||
var app = appSystem.lookup_app(desktopId + ".desktop");
|
||||
var app = appSystem.lookup_app(desktop_id + ".desktop");
|
||||
if (app == null) {
|
||||
this._completeAuthorizeApp(desktopId,
|
||||
GeoclueAccuracyLevel.NONE,
|
||||
timesAllowed,
|
||||
invocation);
|
||||
return;
|
||||
return [false, 0];
|
||||
}
|
||||
|
||||
var name = app.get_name();
|
||||
var icon = app.get_app_info().get_icon();
|
||||
var reason = app.get_string("X-Geoclue-Reason");
|
||||
var allowCallback = function() {
|
||||
this._completeAuthorizeApp(desktopId,
|
||||
reqAccuracyLevel,
|
||||
timesAllowed,
|
||||
invocation);
|
||||
};
|
||||
var denyCallback = function() {
|
||||
this._completeAuthorizeApp(desktopId,
|
||||
GeoclueAccuracyLevel.NONE,
|
||||
timesAllowed,
|
||||
invocation);
|
||||
};
|
||||
|
||||
this._showAppAuthDialog(name,
|
||||
reason,
|
||||
icon,
|
||||
Lang.bind(this, allowCallback),
|
||||
Lang.bind(this, denyCallback));
|
||||
},
|
||||
|
||||
_showAppAuthDialog: function(name, reason, icon, allowCallback, denyCallback) {
|
||||
if (this._dialog == null)
|
||||
this._dialog = new GeolocationDialog(name, reason, icon);
|
||||
else
|
||||
this._dialog.update(name, reason, icon);
|
||||
|
||||
let closedId = this._dialog.connect('closed', function() {
|
||||
this._dialog.disconnect(closedId);
|
||||
if (this._dialog.allowed)
|
||||
allowCallback ();
|
||||
else
|
||||
denyCallback ();
|
||||
}.bind(this));
|
||||
|
||||
this._dialog.open(global.get_current_time ());
|
||||
},
|
||||
|
||||
_completeAuthorizeApp: function(desktopId,
|
||||
accuracyLevel,
|
||||
timesAllowed,
|
||||
invocation) {
|
||||
if (accuracyLevel == GeoclueAccuracyLevel.NONE) {
|
||||
invocation.return_value(GLib.Variant.new('(bu)',
|
||||
[false, accuracyLevel]));
|
||||
this._saveToPermissionStore(desktopId, accuracyLevel, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
let allowedAccuracyLevel = clamp(accuracyLevel,
|
||||
0,
|
||||
this._getMaxAccuracyLevel());
|
||||
invocation.return_value(GLib.Variant.new('(bu)',
|
||||
[true, allowedAccuracyLevel]));
|
||||
|
||||
this._saveToPermissionStore(desktopId, allowedAccuracyLevel, timesAllowed + 1);
|
||||
},
|
||||
|
||||
_fetchPermissionFromStore: function(desktopId, callback) {
|
||||
if (this._permStoreProxy == null) {
|
||||
callback (-1, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this._permStoreProxy.LookupRemote(APP_PERMISSIONS_TABLE,
|
||||
APP_PERMISSIONS_ID,
|
||||
function(result, error) {
|
||||
if (error != null) {
|
||||
log(error.message);
|
||||
callback(-1, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let [permissions, data] = result;
|
||||
let permission = permissions[desktopId];
|
||||
if (permission == null) {
|
||||
callback(-1, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let levelStr = permission[0];
|
||||
let level = GeoclueAccuracyLevel[levelStr.toUpperCase()] ||
|
||||
GeoclueAccuracyLevel.NONE;
|
||||
let timesAllowed = data.get_byte();
|
||||
|
||||
callback(level, timesAllowed);
|
||||
});
|
||||
},
|
||||
|
||||
_saveToPermissionStore: function(desktopId,
|
||||
allowedAccuracyLevel,
|
||||
timesAllowed) {
|
||||
if (timesAllowed > 2 || this._permStoreProxy == null)
|
||||
return;
|
||||
|
||||
let levelStr = Object.keys(GeoclueAccuracyLevel)[allowedAccuracyLevel];
|
||||
let permission = { desktopId: [levelStr] };
|
||||
let permissions = GLib.Variant.new('a{sas}', [permission]));
|
||||
let data = GLib.Variant.new('y', timesAllowed);
|
||||
|
||||
this._permStoreProxy.SetRemote(APP_PERMISSIONS_TABLE,
|
||||
true,
|
||||
APP_PERMISSIONS_ID,
|
||||
permissions,
|
||||
data,
|
||||
function (result, error) {
|
||||
log(error.message);
|
||||
});
|
||||
let allowedAccuracyLevel = clamp(reqAccuracyLevel, 0, this._getMaxAccuracyLevel());
|
||||
return [true, allowedAccuracyLevel];
|
||||
},
|
||||
|
||||
_syncIndicator: function() {
|
||||
if (this._managerProxy == null) {
|
||||
if (this._proxy == null) {
|
||||
this._indicator.visible = false;
|
||||
this._item.actor.visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this._indicator.visible = this._managerProxy.InUse;
|
||||
this._indicator.visible = this._proxy.InUse;
|
||||
this._item.actor.visible = this._indicator.visible;
|
||||
this._updateMenuLabels();
|
||||
},
|
||||
|
||||
_connectToGeoclue: function() {
|
||||
if (this._managerProxy != null || this._connecting)
|
||||
if (this._proxy != null || this._connecting)
|
||||
return false;
|
||||
|
||||
this._connecting = true;
|
||||
new GeoclueManager(Gio.DBus.system,
|
||||
'org.freedesktop.GeoClue2',
|
||||
'/org/freedesktop/GeoClue2/Manager',
|
||||
Lang.bind(this, this._onManagerProxyReady));
|
||||
Lang.bind(this, this._onProxyReady));
|
||||
return true;
|
||||
},
|
||||
|
||||
_onManagerProxyReady: function(proxy, error) {
|
||||
_onProxyReady: function(proxy, error) {
|
||||
if (error != null) {
|
||||
log(error.message);
|
||||
this._connecting = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this._managerProxy = proxy;
|
||||
this._propertiesChangedId = this._managerProxy.connect('g-properties-changed',
|
||||
this._proxy = proxy;
|
||||
this._propertiesChangedId = this._proxy.connect('g-properties-changed',
|
||||
Lang.bind(this, this._onGeocluePropsChanged));
|
||||
|
||||
this._syncIndicator();
|
||||
|
||||
this._managerProxy.AddAgentRemote('gnome-shell', Lang.bind(this, this._onAgentRegistered));
|
||||
this._proxy.AddAgentRemote('gnome-shell', Lang.bind(this, this._onAgentRegistered));
|
||||
},
|
||||
|
||||
_onAgentRegistered: function(result, error) {
|
||||
@@ -314,10 +153,10 @@ const Indicator = new Lang.Class({
|
||||
|
||||
_onGeoclueVanished: function() {
|
||||
if (this._propertiesChangedId) {
|
||||
this._managerProxy.disconnect(this._propertiesChangedId);
|
||||
this._proxy.disconnect(this._propertiesChangedId);
|
||||
this._propertiesChangedId = 0;
|
||||
}
|
||||
this._managerProxy = null;
|
||||
this._proxy = null;
|
||||
|
||||
this._syncIndicator();
|
||||
},
|
||||
@@ -372,85 +211,9 @@ const Indicator = new Lang.Class({
|
||||
let unpacked = properties.deep_unpack();
|
||||
if ("InUse" in unpacked)
|
||||
this._syncIndicator();
|
||||
},
|
||||
|
||||
_connectToPermissionStore: function() {
|
||||
this._permStoreProxy = null;
|
||||
new PermissionStore(Gio.DBus.session,
|
||||
'org.freedesktop.XdgApp',
|
||||
'/org/freedesktop/XdgApp/PermissionStore',
|
||||
Lang.bind(this, this._onPermStoreProxyReady));
|
||||
},
|
||||
|
||||
_onPermStoreProxyReady: function(proxy, error) {
|
||||
if (error != null) {
|
||||
log(error.message);
|
||||
return;
|
||||
}
|
||||
|
||||
this._permStoreProxy = proxy;
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
function clamp(value, min, max) {
|
||||
return Math.max(min, Math.min(max, value));
|
||||
}
|
||||
|
||||
const GeolocationDialog = new Lang.Class({
|
||||
Name: 'GeolocationDialog',
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
|
||||
// FIXME: Would be nice to show the application icon too
|
||||
_init: function(name, reason, icon) {
|
||||
this.parent({ destroyOnClose: false });
|
||||
|
||||
let text = _("'%s' is requesting access to location data.").format (name);
|
||||
this._label = new St.Label({ style_class: 'prompt-dialog-description',
|
||||
text: text });
|
||||
|
||||
this.contentLayout.add(this._label, {});
|
||||
|
||||
if (reason != null) {
|
||||
this._reasonLabel = new St.Label({ style_class: 'prompt-dialog-description',
|
||||
text: reason });
|
||||
this.contentLayout.add(this._reasonLabel, {});
|
||||
} else {
|
||||
this._reasonLabel = null;
|
||||
}
|
||||
|
||||
this._allowButton = this.addButton({ label: _("Confirm"),
|
||||
action: this._onAllowClicked.bind(this),
|
||||
default: false },
|
||||
{ expand: true, x_fill: false, x_align: St.Align.END });
|
||||
this._denyButton = this.addButton({ label: _("Cancel"),
|
||||
action: this._onDisallowClicked.bind(this),
|
||||
default: true },
|
||||
{ expand: true, x_fill: false, x_align: St.Align.START });
|
||||
},
|
||||
|
||||
update: function(name, reason, icon) {
|
||||
let text = _("'%s' is requesting access to location data.").format (name);
|
||||
this._label.text = text;
|
||||
|
||||
if (this._reasonLabel != null) {
|
||||
this.contentLayout.remove(this._reasonLabel, {});
|
||||
this._reasonLabel = null;
|
||||
}
|
||||
|
||||
if (reason != null) {
|
||||
this._reasonLabel = new St.Label({ style_class: 'prompt-dialog-description',
|
||||
text: reason });
|
||||
this.contentLayout.add(this._reasonLabel, {});
|
||||
}
|
||||
},
|
||||
|
||||
_onAllowClicked: function() {
|
||||
this.allowed = true;
|
||||
this.close();
|
||||
},
|
||||
|
||||
_onDisallowClicked: function() {
|
||||
this.allowed = false;
|
||||
this.close();
|
||||
}
|
||||
});
|
||||
|
@@ -363,6 +363,8 @@ shell_network_agent_get_secrets (NMSecretAgent *agent,
|
||||
{
|
||||
ShellNetworkAgent *self = SHELL_NETWORK_AGENT (agent);
|
||||
ShellAgentRequest *request;
|
||||
NMSettingConnection *setting_connection;
|
||||
const char *connection_type;
|
||||
GHashTable *attributes;
|
||||
char *request_id;
|
||||
|
||||
@@ -376,6 +378,9 @@ shell_network_agent_get_secrets (NMSecretAgent *agent,
|
||||
shell_agent_request_cancel (request);
|
||||
}
|
||||
|
||||
setting_connection = nm_connection_get_setting_connection (connection);
|
||||
connection_type = nm_setting_connection_get_connection_type (setting_connection);
|
||||
|
||||
request = g_slice_new (ShellAgentRequest);
|
||||
request->self = g_object_ref (self);
|
||||
request->cancellable = g_cancellable_new ();
|
||||
@@ -385,7 +390,7 @@ shell_network_agent_get_secrets (NMSecretAgent *agent,
|
||||
request->flags = flags;
|
||||
request->callback = callback;
|
||||
request->callback_data = callback_data;
|
||||
request->is_vpn = !strcmp(setting_name, NM_SETTING_VPN_SETTING_NAME);
|
||||
request->is_vpn = !strcmp(connection_type, NM_SETTING_VPN_SETTING_NAME);
|
||||
request->entries = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, gvalue_destroy_notify);
|
||||
|
||||
if (request->is_vpn)
|
||||
|
@@ -80,7 +80,6 @@ struct _ShellRecorder {
|
||||
guint redraw_timeout;
|
||||
guint redraw_idle;
|
||||
guint update_memory_used_timeout;
|
||||
guint update_pointer_timeout;
|
||||
guint repaint_hook_id;
|
||||
};
|
||||
|
||||
@@ -126,11 +125,6 @@ G_DEFINE_TYPE(ShellRecorder, shell_recorder, G_TYPE_OBJECT);
|
||||
*/
|
||||
#define DEFAULT_FRAMES_PER_SECOND 30
|
||||
|
||||
/* The time (in milliseconds) between querying the server for the cursor
|
||||
* position.
|
||||
*/
|
||||
#define UPDATE_POINTER_TIME 100
|
||||
|
||||
/* The time we wait (in milliseconds) before redrawing when the memory used
|
||||
* changes.
|
||||
*/
|
||||
@@ -537,7 +531,8 @@ on_cursor_changed (MetaCursorTracker *tracker,
|
||||
}
|
||||
|
||||
static void
|
||||
recorder_update_pointer (ShellRecorder *recorder)
|
||||
on_cursor_position_changed (MetaCursorTracker *tracker,
|
||||
ShellRecorder *recorder)
|
||||
{
|
||||
int pointer_x, pointer_y;
|
||||
|
||||
@@ -551,36 +546,6 @@ recorder_update_pointer (ShellRecorder *recorder)
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
recorder_update_pointer_timeout (gpointer data)
|
||||
{
|
||||
recorder_update_pointer (data);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
recorder_add_update_pointer_timeout (ShellRecorder *recorder)
|
||||
{
|
||||
if (!recorder->update_pointer_timeout)
|
||||
{
|
||||
recorder->update_pointer_timeout = g_timeout_add (UPDATE_POINTER_TIME,
|
||||
recorder_update_pointer_timeout,
|
||||
recorder);
|
||||
g_source_set_name_by_id (recorder->update_pointer_timeout, "[gnome-shell] recorder_update_pointer_timeout");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
recorder_remove_update_pointer_timeout (ShellRecorder *recorder)
|
||||
{
|
||||
if (recorder->update_pointer_timeout)
|
||||
{
|
||||
g_source_remove (recorder->update_pointer_timeout);
|
||||
recorder->update_pointer_timeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
recorder_connect_stage_callbacks (ShellRecorder *recorder)
|
||||
{
|
||||
@@ -652,6 +617,8 @@ recorder_set_screen (ShellRecorder *recorder,
|
||||
recorder->cursor_tracker = tracker;
|
||||
g_signal_connect_object (tracker, "cursor-changed",
|
||||
G_CALLBACK (on_cursor_changed), recorder, 0);
|
||||
g_signal_connect_object (tracker, "position-changed",
|
||||
G_CALLBACK (on_cursor_position_changed), recorder, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1514,7 +1481,7 @@ shell_recorder_record (ShellRecorder *recorder,
|
||||
|
||||
recorder->state = RECORDER_STATE_RECORDING;
|
||||
recorder_update_pointer (recorder);
|
||||
recorder_add_update_pointer_timeout (recorder);
|
||||
meta_cursor_tracker_enable_track_position (recorder->cursor_tracker);
|
||||
|
||||
/* Disable unredirection while we are recoring */
|
||||
meta_disable_unredirect_for_screen (shell_global_get_screen (shell_global_get ()));
|
||||
@@ -1553,7 +1520,7 @@ shell_recorder_close (ShellRecorder *recorder)
|
||||
*/
|
||||
clutter_actor_paint (CLUTTER_ACTOR (recorder->stage));
|
||||
|
||||
recorder_remove_update_pointer_timeout (recorder);
|
||||
meta_cursor_tracker_disable_track_position (recorder->cursor_tracker);
|
||||
recorder_close_pipeline (recorder);
|
||||
|
||||
/* Queue a redraw to remove the recording indicator */
|
||||
|
Reference in New Issue
Block a user