Skip to content
This repository has been archived by the owner on Mar 27, 2022. It is now read-only.

Commit

Permalink
retrofit _with_window_actor to detect not-yeat ready windows; may fix #…
Browse files Browse the repository at this point in the history
  • Loading branch information
timbertson committed Aug 30, 2017
1 parent aaf33b6 commit 9b7b4f7
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 61 deletions.
2 changes: 1 addition & 1 deletion src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ interface Logger {
}

interface Lang {
bind<T>(subject:Object, fn:Function):T
bind(subject:Object, fn:Function):Function
}

function assert<T extends Object>(x:T) {
Expand Down
43 changes: 9 additions & 34 deletions src/gjs/mutter_window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ module MutterWindow {
return w.get_stable_sequence();
}

static is_ready(w: MetaWindow) {
var rect = w.get_frame_rect();
if (rect.width == 0 || rect.height == 0) {
Util.log.warn("is_ready() returning false due to zero-sized frame");
return false;
}
return true;
}

private static is_resizeable(w:MetaWindow):boolean {
return w.resizeable;
}
Expand Down Expand Up @@ -88,21 +97,6 @@ module MutterWindow {
// this.log.debug("window " + this + " with type == " + window_type + " can" + (result ? "" : " NOT") + " be tiled");
return result;
}

static get_actor(w:MetaWindow):GObject {
try {
// terribly unobvious name for "this MetaWindow's associated MetaWindowActor"
return w.get_compositor_private();
} catch (e) {
// not implemented for some special windows - ignore them
Util.log.warn("couldn't call get_compositor_private for window " + w, e);
if(w.get_compositor_private) {
Util.log.warn("But the function exists! aborting...");
throw(e);
}
}
return null;
}
}

export class Window implements Tiling.Window, SignalOwner {
Expand Down Expand Up @@ -211,24 +205,5 @@ module MutterWindow {
size: { x: r.width, y:r.height }
};
}

private get_actor() {
return WindowProperties.get_actor(this.meta_window);
}

// proxy signals through to actor. If we attach signals directly to the actor, it
// disappears before we can detach them and we leak BoundSignal objects.
connect(name:string, cb) {
var actor = this.get_actor();
return actor.connect.apply(actor, arguments);
}
disconnect(sig) {
var actor = this.get_actor();
if (!actor) {
this.log.debug("Can't disconnect signal - actor is destroyed");
return;
}
return actor.disconnect.apply(actor, arguments);
}
}
}
46 changes: 20 additions & 26 deletions src/gjs/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ module Workspace {
var Lang = imports.lang;
var Meta = imports.gi.Meta;
var WindowProperties = MutterWindow.WindowProperties;
var SIGNALS_ON_ACTORS = !Util.shell_version_gte(3,11);

export interface Change {
pending: boolean
Expand Down Expand Up @@ -319,27 +318,31 @@ module Workspace {
else this.log.debug("ducking grab op...");
}

// TODO: this can go away once we drop support for 0.10
_with_window_actor(meta_window:MetaWindow, cb:VoidFunc, initial?:boolean) {
_with_ready_window(meta_window:MetaWindow, cb:VoidFunc) {
// Trying to act too quickly on a window can cause race
// conditions and segfaults, e.g. https://github.com/timbertson/shellshape/issues/169

var self:Workspace = this;
var actor = MutterWindow.WindowProperties.get_actor(meta_window);
if (actor) {
cb();
} else {
if (initial === false) {
self.log.warn("actor unavailable for " + meta_window.get_title());
return;
function attempt(remainingAttempts: number) {
if (MutterWindow.WindowProperties.is_ready(meta_window)) {
cb();
} else {
if (remainingAttempts === 0) {
self.log.warn("Valid window unavailable for " + meta_window.get_title());
return;
}
Mainloop.idle_add(function() {
attempt(remainingAttempts-1);
return false;
});
}
Mainloop.idle_add(function() {
self._with_window_actor(meta_window, cb, false);
return false;
});
}
attempt(5);
}

private connect_window_signals(win:MutterWindow.Window) {
var self:Workspace = this;
var emitter = SIGNALS_ON_ACTORS ? win : win.meta_window;
var emitter = win.meta_window;
var bind_to_window_change = function(event_name, relevant_grabs, cb) {
// we only care about events *after* at least one relevant grab_op,
var signal_handler = self._grab_op_signal_handler({pending:false}, relevant_grabs, {
Expand All @@ -364,16 +367,12 @@ module Workspace {

private disconnect_window_signals(win:MutterWindow.Window) {
this.log.debug("Disconnecting signals from " + win);
if (SIGNALS_ON_ACTORS) {
// `win` acts as a proxy for the actor which doesn't get GC'd behind our back
Util.disconnect_tracked_signals(this, win);
}
Util.disconnect_tracked_signals(this, win.meta_window);
}

on_window_create:{(w:MetaWindow, reason?:string):void} = _duck_turbulence(_duck_overview(function(meta_window:MetaWindow, reason?:string) {
var self:Workspace = this;
self._with_window_actor(meta_window, function() {
self._with_ready_window(meta_window, function() {
var ws = meta_window.get_workspace();
if(!WindowProperties.can_be_tiled(meta_window)) {
// self.log.debug("can\'t be tiled");
Expand All @@ -391,6 +390,7 @@ module Workspace {
}

var win = self.extension.get_window(meta_window);

self.log.debug("on_window_create for " + win);
var added = self.layout.add(win, self.extension.focus_window);
if (!added) {
Expand Down Expand Up @@ -495,10 +495,4 @@ module Workspace {
}
}
}

if (!SIGNALS_ON_ACTORS) {
Workspace.prototype._with_window_actor = function(meta_window:MetaWindow, cb, initial?:boolean) {
cb();
};
}
}

0 comments on commit 9b7b4f7

Please sign in to comment.