[gnome] Update extensions for v46
This commit is contained in:
@ -81,6 +81,14 @@ export class FeatureMenuToggle extends QuickMenuToggle {
|
||||
))
|
||||
);
|
||||
|
||||
this.menu.addMenuItem(
|
||||
(this._focusMovePointer = new SettingsPopupSwitch(
|
||||
_("Move Pointer with the Focus"),
|
||||
this.extension,
|
||||
"move-pointer-focus-enabled"
|
||||
))
|
||||
);
|
||||
|
||||
// Add an entry-point for more settings
|
||||
this.menu.addMenuItem(new PopupSeparatorMenuItem());
|
||||
const settingsItem = this.menu.addAction(_("Settings"), () => this.extension.openPreferences());
|
||||
|
||||
@ -79,6 +79,7 @@ export class Node extends GObject.Object {
|
||||
this.tab = null;
|
||||
this.decoration = null;
|
||||
this.app = null;
|
||||
this.pointer = null;
|
||||
|
||||
if (this.isWindow()) {
|
||||
// When destroy() is called on Meta.Window, it might not be
|
||||
@ -474,9 +475,9 @@ export class Node extends GObject.Object {
|
||||
child: new St.Icon({ icon_name: "window-close-symbolic" }),
|
||||
});
|
||||
|
||||
tabContents.add(iconBin);
|
||||
tabContents.add(titleButton);
|
||||
tabContents.add(closeButton);
|
||||
tabContents.add_child(iconBin);
|
||||
tabContents.add_child(titleButton);
|
||||
tabContents.add_child(closeButton);
|
||||
|
||||
let clickFn = () => {
|
||||
this.parentNode.childNodes.forEach((c) => {
|
||||
@ -553,6 +554,17 @@ export class Node extends GObject.Object {
|
||||
set tile(value) {
|
||||
this.float = !value;
|
||||
}
|
||||
|
||||
resetLayoutSingleChild() {
|
||||
let tabbedOrStacked = this.isTabbed() || this.isStacked();
|
||||
if (tabbedOrStacked && this.singleOrNoChild()) {
|
||||
this.layout = LAYOUT_TYPES.HSPLIT;
|
||||
}
|
||||
}
|
||||
|
||||
singleOrNoChild() {
|
||||
return this.childNodes.length <= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -946,6 +958,7 @@ export class Tree extends Node {
|
||||
}
|
||||
this.resetSiblingPercent(parentNode);
|
||||
this.resetSiblingPercent(parentTarget);
|
||||
parentNode.resetLayoutSingleChild();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -953,7 +966,7 @@ export class Tree extends Node {
|
||||
* Give the next sibling/parent/descendant on the tree based
|
||||
* on a given Meta.MotionDirection
|
||||
*
|
||||
* @param {Tree.Node} node
|
||||
* @param {Node} node
|
||||
* @param {Meta.MotionDirection} direction
|
||||
*
|
||||
* Credits: borrowed logic from tree.c of i3
|
||||
@ -1511,7 +1524,7 @@ export class Tree extends Node {
|
||||
} else {
|
||||
decoration.hide();
|
||||
}
|
||||
if (!decoration.contains(child.tab)) decoration.add(child.tab);
|
||||
if (!decoration.contains(child.tab)) decoration.add_child(child.tab);
|
||||
}
|
||||
|
||||
child.render();
|
||||
@ -1561,7 +1574,23 @@ export class Tree extends Node {
|
||||
}
|
||||
|
||||
debugTree() {
|
||||
// this.debugChildNodes(this);
|
||||
}
|
||||
|
||||
debugChildNodes(node) {
|
||||
this.debugNode(this);
|
||||
node.childNodes.forEach((child) => {
|
||||
this.debugChildNodes(child);
|
||||
});
|
||||
}
|
||||
|
||||
debugParentNodes(node) {
|
||||
if (node) {
|
||||
if (node.parentNode) {
|
||||
this.debugParentNodes(node.parentNode);
|
||||
}
|
||||
this.debugNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
debugNode(node) {
|
||||
@ -1576,7 +1605,7 @@ export class Tree extends Node {
|
||||
|
||||
let attributes = "";
|
||||
|
||||
if (node.isWindow()) {
|
||||
if (node.isWindow && node.isWindow()) {
|
||||
let metaWindow = node.nodeValue;
|
||||
attributes += `class:'${metaWindow.get_wm_class()}',title:'${
|
||||
metaWindow.title
|
||||
@ -1590,6 +1619,9 @@ export class Tree extends Node {
|
||||
|
||||
if (node.rect) {
|
||||
attributes += `,rect:${node.rect.width}x${node.rect.height}+${node.rect.x}+${node.rect.y}`;
|
||||
const pointerCoord = global.get_pointer();
|
||||
const pointerInside = Utils.rectContainsPoint(node.rect, pointerCoord) ? "yes" : "no";
|
||||
attributes += `,pointer:${pointerInside}`;
|
||||
}
|
||||
|
||||
if (level !== 0) Logger.debug(`${spacing}|`);
|
||||
@ -1598,10 +1630,6 @@ export class Tree extends Node {
|
||||
node.index !== null ? node.index : "-"
|
||||
} @${attributes}`
|
||||
);
|
||||
|
||||
node.childNodes.forEach((child) => {
|
||||
this.debugNode(child);
|
||||
});
|
||||
}
|
||||
|
||||
findParent(childNode, parentNodeType) {
|
||||
|
||||
@ -68,49 +68,46 @@ export class WindowManager extends GObject.Object {
|
||||
!production ? "DEV" : `${PACKAGE_VERSION}-${ext.metadata.version}`
|
||||
}`;
|
||||
this.windowProps = this.ext.configMgr.windowProps;
|
||||
this.windowProps.overrides = this.windowProps.overrides.filter((override) => !override.wmId);
|
||||
this._kbd = this.ext.keybindings;
|
||||
this._tree = new Tree(this);
|
||||
this.eventQueue = new Queue();
|
||||
this.theme = this.ext.theme;
|
||||
this.lastFocusedWindow = null;
|
||||
Logger.info("forge initialized");
|
||||
}
|
||||
|
||||
addFloatOverride(metaWindow, byClass = true) {
|
||||
addFloatOverride(metaWindow, withWmId) {
|
||||
let overrides = this.windowProps.overrides;
|
||||
let wmTitle = metaWindow.get_title();
|
||||
let wmClass = metaWindow.get_wm_class();
|
||||
let wmId = metaWindow.get_id();
|
||||
|
||||
for (let override in overrides) {
|
||||
if (!byClass) {
|
||||
if (override.wmClass === wmClass && override.wmTitle === wmTitle) return;
|
||||
} else {
|
||||
if (override.wmClass === wmClass && !override.wmTitle) return;
|
||||
}
|
||||
// if the window is already floating
|
||||
if (override.wmClass === wmClass && override.mode === "float" && !override.wmTitle) return;
|
||||
}
|
||||
overrides.push({
|
||||
wmClass: wmClass,
|
||||
wmTitle: !byClass ? wmTitle : undefined,
|
||||
wmId: withWmId ? wmId : undefined,
|
||||
mode: "float",
|
||||
});
|
||||
this.windowProps.overrides = overrides;
|
||||
this.ext.configMgr.windowProps = this.windowProps;
|
||||
}
|
||||
|
||||
removeFloatOverride(metaWindow, byClass = true) {
|
||||
removeFloatOverride(metaWindow, withWmId) {
|
||||
let overrides = this.windowProps.overrides;
|
||||
let wmTitle = metaWindow.get_title();
|
||||
let wmClass = metaWindow.get_wm_class();
|
||||
|
||||
if (byClass) {
|
||||
// remove purely wmClass - by checking also if override title exists
|
||||
overrides = overrides.filter(
|
||||
(override) => !(override.wmClass === wmClass) && !override.wmTitle
|
||||
);
|
||||
} else {
|
||||
overrides = overrides.filter(
|
||||
(override) => !(override.wmClass === wmClass && override.wmTitle === wmTitle)
|
||||
);
|
||||
}
|
||||
let wmId = metaWindow.get_id();
|
||||
overrides = overrides.filter(
|
||||
(override) =>
|
||||
!(
|
||||
override.wmClass === wmClass &&
|
||||
// rules with a Title are written by the user and peristent
|
||||
!override.wmTitle &&
|
||||
(!withWmId || override.wmId === wmId)
|
||||
)
|
||||
);
|
||||
|
||||
this.windowProps.overrides = overrides;
|
||||
this.ext.configMgr.windowProps = this.windowProps;
|
||||
@ -121,26 +118,18 @@ export class WindowManager extends GObject.Object {
|
||||
if (!nodeWindow || !(action || action.mode)) return;
|
||||
if (nodeWindow.nodeType !== NODE_TYPES.WINDOW) return;
|
||||
|
||||
let floatToggle = action.name === "FloatToggle";
|
||||
let floatClassToggle = action.name === "FloatClassToggle";
|
||||
let withWmId = action.name === "FloatToggle";
|
||||
let floatingExempt = this.isFloatingExempt(metaWindow);
|
||||
|
||||
if (floatingExempt) {
|
||||
if (floatClassToggle) {
|
||||
this.removeFloatOverride(metaWindow);
|
||||
} else if (floatToggle) {
|
||||
this.removeFloatOverride(metaWindow, false);
|
||||
}
|
||||
nodeWindow.mode = WINDOW_MODES.TILE;
|
||||
this.removeFloatOverride(metaWindow, withWmId);
|
||||
if (!this.isActiveWindowWorkspaceTiled(metaWindow)) {
|
||||
nodeWindow.mode = WINDOW_MODES.FLOAT;
|
||||
} else {
|
||||
nodeWindow.mode = WINDOW_MODES.TILE;
|
||||
}
|
||||
} else {
|
||||
if (floatClassToggle) {
|
||||
this.addFloatOverride(metaWindow);
|
||||
} else if (floatToggle) {
|
||||
this.addFloatOverride(metaWindow, false);
|
||||
}
|
||||
this.addFloatOverride(metaWindow, withWmId);
|
||||
nodeWindow.mode = WINDOW_MODES.FLOAT;
|
||||
}
|
||||
}
|
||||
@ -350,6 +339,7 @@ export class WindowManager extends GObject.Object {
|
||||
const focusNodeWindow = this.tree.findNode(this.focusMetaWindow);
|
||||
this.updateStackedFocus(focusNodeWindow);
|
||||
this.updateTabbedFocus(focusNodeWindow);
|
||||
this.movePointerWith(focusNodeWindow);
|
||||
},
|
||||
};
|
||||
this.queueEvent(eventObj);
|
||||
@ -444,6 +434,7 @@ export class WindowManager extends GObject.Object {
|
||||
let currentLayout;
|
||||
|
||||
switch (action.name) {
|
||||
case "FloatNonPersistentToggle":
|
||||
case "FloatToggle":
|
||||
case "FloatClassToggle":
|
||||
this.toggleFloatingMode(action, focusWindow);
|
||||
@ -499,6 +490,7 @@ export class WindowManager extends GObject.Object {
|
||||
if (prev) prev.parentNode.lastTabFocus = prev.nodeValue;
|
||||
this.renderTree("move-tabbed-queue");
|
||||
}
|
||||
this.movePointerWith(focusNodeWindow);
|
||||
}
|
||||
},
|
||||
});
|
||||
@ -523,6 +515,7 @@ export class WindowManager extends GObject.Object {
|
||||
focusNodeWindow.nodeValue.raise();
|
||||
this.updateTabbedFocus(focusNodeWindow);
|
||||
this.updateStackedFocus(focusNodeWindow);
|
||||
this.movePointerWith(focusNodeWindow);
|
||||
this.renderTree("swap", true);
|
||||
break;
|
||||
case "Split":
|
||||
@ -679,6 +672,7 @@ export class WindowManager extends GObject.Object {
|
||||
);
|
||||
let lastActiveNodeWindow = this.tree.findNode(lastActiveWindow);
|
||||
this.tree.swapPairs(lastActiveNodeWindow, focusNodeWindow);
|
||||
this.movePointerWith(focusNodeWindow);
|
||||
this.renderTree("swap-last-active");
|
||||
}
|
||||
break;
|
||||
@ -914,7 +908,7 @@ export class WindowManager extends GObject.Object {
|
||||
try {
|
||||
nodeWindow.tab.remove_style_class_name("window-tabbed-tab-active");
|
||||
} catch (e) {
|
||||
Logger.warn(e);
|
||||
// Logger.warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1425,6 +1419,8 @@ export class WindowManager extends GObject.Object {
|
||||
this.updateDecorationLayout();
|
||||
this.updateStackedFocus();
|
||||
this.updateTabbedFocus();
|
||||
let focusNodeWindow = this.tree.findNode(this.focusMetaWindow);
|
||||
this.movePointerWith(focusNodeWindow);
|
||||
},
|
||||
});
|
||||
let focusNodeWindow = this.tree.findNode(this.focusMetaWindow);
|
||||
@ -1495,6 +1491,8 @@ export class WindowManager extends GObject.Object {
|
||||
.get_workspace()
|
||||
.activate_with_focus(metaWindow, global.display.get_current_time());
|
||||
this.moveCenter(metaWindow);
|
||||
} else {
|
||||
this.movePointerWith(metaWindow);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1613,9 +1611,10 @@ export class WindowManager extends GObject.Object {
|
||||
let nodeWindow;
|
||||
nodeWindow = this.tree.findNodeByActor(actor);
|
||||
|
||||
if (nodeWindow) {
|
||||
if (nodeWindow?.isWindow()) {
|
||||
this.tree.removeNode(nodeWindow);
|
||||
this.renderTree("window-destroy-quick", true);
|
||||
this.removeFloatOverride(nodeWindow.nodeValue, true);
|
||||
}
|
||||
|
||||
// find the next attachNode here
|
||||
@ -1777,10 +1776,26 @@ export class WindowManager extends GObject.Object {
|
||||
*/
|
||||
movePointerWith(nodeWindow) {
|
||||
if (!nodeWindow || !nodeWindow._data) return;
|
||||
let rect = nodeWindow._data.get_frame_rect();
|
||||
global.get_pointer();
|
||||
const seat = Clutter.get_default_backend().get_default_seat();
|
||||
seat.warp_pointer(rect.x, rect.y);
|
||||
if (this.ext.settings.get_boolean("move-pointer-focus-enabled")) {
|
||||
this.storePointerLastPosition(this.lastFocusedWindow);
|
||||
if (this.canMovePointerInsideNodeWindow(nodeWindow)) {
|
||||
this.warpPointerToNodeWindow(nodeWindow);
|
||||
}
|
||||
}
|
||||
this.lastFocusedWindow = nodeWindow;
|
||||
this.tree.debugParentNodes(nodeWindow);
|
||||
}
|
||||
|
||||
warpPointerToNodeWindow(nodeWindow) {
|
||||
const newCoord = this.getPointerPositionInside(nodeWindow);
|
||||
if (newCoord && newCoord.x && newCoord.y) {
|
||||
const seat = Clutter.get_default_backend().get_default_seat();
|
||||
if (seat) {
|
||||
const wmTitle = nodeWindow.nodeValue.get_title();
|
||||
Logger.debug(`moved pointer to [${wmTitle}] at (${newCoord.x},${newCoord.y})`);
|
||||
seat.warp_pointer(newCoord.x, newCoord.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getPointer() {
|
||||
@ -1820,6 +1835,7 @@ export class WindowManager extends GObject.Object {
|
||||
const horizontal = parentNodeTarget.isHSplit() || parentNodeTarget.isTabbed();
|
||||
const isMonParent = parentNodeTarget.nodeType === NODE_TYPES.MONITOR;
|
||||
const isConParent = parentNodeTarget.nodeType === NODE_TYPES.CON;
|
||||
const centerLayout = this.ext.settings.get_string("dnd-center-layout").toUpperCase();
|
||||
const stacked = parentNodeTarget.isStacked();
|
||||
const tabbed = parentNodeTarget.isTabbed();
|
||||
const stackedOrTabbed = stacked || tabbed;
|
||||
@ -1917,28 +1933,35 @@ export class WindowManager extends GObject.Object {
|
||||
const isCenter = Utils.rectContainsPoint(centerRegion, currPointer);
|
||||
|
||||
if (isCenter) {
|
||||
if (stackedOrTabbed) {
|
||||
containerNode = parentNodeTarget;
|
||||
referenceNode = null;
|
||||
if (centerLayout == "SWAP") {
|
||||
referenceNode = nodeWinAtPointer;
|
||||
previewParams = {
|
||||
className: stacked ? "window-tilepreview-stacked" : "window-tilepreview-tabbed",
|
||||
targetRect: targetRect,
|
||||
};
|
||||
} else {
|
||||
if (isMonParent) {
|
||||
childNode.createCon = true;
|
||||
if (stackedOrTabbed) {
|
||||
containerNode = parentNodeTarget;
|
||||
referenceNode = nodeWinAtPointer;
|
||||
referenceNode = null;
|
||||
previewParams = {
|
||||
className: stacked ? "window-tilepreview-stacked" : "window-tilepreview-tabbed",
|
||||
targetRect: targetRect,
|
||||
};
|
||||
} else {
|
||||
containerNode = parentNodeTarget;
|
||||
referenceNode = null;
|
||||
const parentTargetRect = this.tree.processGap(parentNodeTarget);
|
||||
previewParams = {
|
||||
targetRect: parentTargetRect,
|
||||
};
|
||||
if (isMonParent) {
|
||||
childNode.createCon = true;
|
||||
containerNode = parentNodeTarget;
|
||||
referenceNode = nodeWinAtPointer;
|
||||
previewParams = {
|
||||
targetRect: targetRect,
|
||||
};
|
||||
} else {
|
||||
containerNode = parentNodeTarget;
|
||||
referenceNode = null;
|
||||
const parentTargetRect = this.tree.processGap(parentNodeTarget);
|
||||
previewParams = {
|
||||
targetRect: parentTargetRect,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (isLeft) {
|
||||
@ -2117,7 +2140,6 @@ export class WindowManager extends GObject.Object {
|
||||
} else if (isTop || isBottom) {
|
||||
childNode.layout = LAYOUT_TYPES.VSPLIT;
|
||||
} else if (isCenter) {
|
||||
const centerLayout = this.ext.settings.get_string("dnd-center-layout").toUpperCase();
|
||||
childNode.layout = LAYOUT_TYPES[centerLayout];
|
||||
}
|
||||
} else if (childNode.detachWindow) {
|
||||
@ -2125,6 +2147,9 @@ export class WindowManager extends GObject.Object {
|
||||
isLeft || isRight ? ORIENTATION_TYPES.HORIZONTAL : ORIENTATION_TYPES.VERTICAL;
|
||||
this.tree.split(childNode, orientation);
|
||||
containerNode.insertBefore(childNode.parentNode, referenceNode);
|
||||
} else if (isCenter && centerLayout == "SWAP") {
|
||||
this.tree.swapPairs(referenceNode, focusNodeWindow);
|
||||
this.renderTree("drag-swap");
|
||||
} else {
|
||||
// Child Node is a WINDOW
|
||||
containerNode.insertBefore(childNode, referenceNode);
|
||||
@ -2134,11 +2159,11 @@ export class WindowManager extends GObject.Object {
|
||||
if (!stackedOrTabbed) containerNode.layout = LAYOUT_TYPES.VSPLIT;
|
||||
} else if (isCenter) {
|
||||
if (containerNode.isHSplit() || containerNode.isVSplit()) {
|
||||
const centerLayout = this.ext.settings.get_string("dnd-center-layout").toUpperCase();
|
||||
containerNode.layout = LAYOUT_TYPES[centerLayout];
|
||||
}
|
||||
}
|
||||
}
|
||||
previousParent.resetLayoutSingleChild();
|
||||
} else {
|
||||
updatePreview(focusNodeWindow, previewParams);
|
||||
}
|
||||
@ -2147,6 +2172,70 @@ export class WindowManager extends GObject.Object {
|
||||
}
|
||||
}
|
||||
|
||||
canMovePointerInsideNodeWindow(nodeWindow) {
|
||||
if (nodeWindow && nodeWindow._data) {
|
||||
const metaWindow = nodeWindow.nodeValue;
|
||||
const metaRect = metaWindow.get_frame_rect();
|
||||
const pointerCoord = global.get_pointer();
|
||||
return (
|
||||
metaRect &&
|
||||
// xdg-copy creates a 1x1 pixel window to capture mouse events.
|
||||
metaRect.width > 8 &&
|
||||
metaRect.height > 8 &&
|
||||
!Utils.rectContainsPoint(metaRect, pointerCoord) &&
|
||||
!metaWindow.minimized &&
|
||||
!Main.overview.visible &&
|
||||
!this.pointerIsOverParentDecoration(nodeWindow, pointerCoord)
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pointerIsOverParentDecoration(nodeWindow, pointerCoord) {
|
||||
if (pointerCoord && nodeWindow && nodeWindow.parentNode) {
|
||||
let node = nodeWindow.parentNode;
|
||||
if (node.isTabbed() || node.isStacked()) {
|
||||
return Utils.rectContainsPoint(node.rect, pointerCoord);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
getPointerPositionInside(nodeWindow) {
|
||||
if (nodeWindow && nodeWindow._data) {
|
||||
const metaWindow = nodeWindow.nodeValue;
|
||||
const metaRect = metaWindow.get_frame_rect();
|
||||
// on: last position of cursor inside window
|
||||
// on: titlebar: near to app toolbars, menubar, tabs, etc...
|
||||
let [wx, wy] = nodeWindow.pointer
|
||||
? [nodeWindow.pointer.x, nodeWindow.pointer.y]
|
||||
: [metaRect.width / 2, 8];
|
||||
let px = wx >= metaRect.width ? metaRect.width - 8 : wx;
|
||||
let py = wy >= metaRect.height ? metaRect.height - 8 : wy;
|
||||
return {
|
||||
x: metaRect.x + px,
|
||||
y: metaRect.y + py,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
storePointerLastPosition(nodeWindow) {
|
||||
if (nodeWindow && nodeWindow._data) {
|
||||
const metaWindow = nodeWindow.nodeValue;
|
||||
const metaRect = metaWindow.get_frame_rect();
|
||||
const pointerCoord = global.get_pointer();
|
||||
if (Utils.rectContainsPoint(metaRect, pointerCoord)) {
|
||||
let px = pointerCoord[0] - metaRect.x;
|
||||
let py = pointerCoord[1] - metaRect.y;
|
||||
if (px > 0 && py > 0) {
|
||||
nodeWindow.pointer = { x: px, y: py };
|
||||
Logger.debug(`stored pointer for [${metaWindow.get_title()}] at (${px},${py})`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
findNodeWindowAtPointer(focusNodeWindow) {
|
||||
let pointerCoord = global.get_pointer();
|
||||
|
||||
@ -2451,37 +2540,34 @@ export class WindowManager extends GObject.Object {
|
||||
knownFloats.filter((kf) => {
|
||||
let matchTitle = false;
|
||||
let matchClass = false;
|
||||
let matchId = false;
|
||||
|
||||
if (kf.wmTitle) {
|
||||
if (kf.wmTitle === " ") {
|
||||
matchTitle = kf.wmTitle === windowTitle;
|
||||
} else {
|
||||
let titles = kf.wmTitle.split(",");
|
||||
matchTitle = titles.filter((t) => {
|
||||
if (windowTitle) {
|
||||
if (t.startsWith('!')) {
|
||||
return !windowTitle.includes(t.slice(1))
|
||||
} else {
|
||||
return windowTitle.includes(t)
|
||||
matchTitle =
|
||||
titles.filter((t) => {
|
||||
if (windowTitle) {
|
||||
if (t.startsWith("!")) {
|
||||
return !windowTitle.includes(t.slice(1));
|
||||
} else {
|
||||
return windowTitle.includes(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}).length > 0;
|
||||
return false;
|
||||
}).length > 0;
|
||||
}
|
||||
}
|
||||
if (kf.wmClass) {
|
||||
matchClass = kf.wmClass.includes(metaWindow.get_wm_class());
|
||||
}
|
||||
|
||||
if (kf.wmClass && kf.wmTitle) {
|
||||
return matchTitle && matchClass;
|
||||
} else {
|
||||
if (kf.wmTitle) {
|
||||
return matchTitle;
|
||||
} else {
|
||||
return matchClass;
|
||||
}
|
||||
if (kf.wmId) {
|
||||
matchId = kf.wmId === metaWindow.get_id();
|
||||
}
|
||||
|
||||
return (!kf.wmId || matchId) && (!kf.wmTitle || matchTitle) && matchClass;
|
||||
}).length > 0;
|
||||
|
||||
return floatByType || floatOverride;
|
||||
|
||||
@ -101,6 +101,7 @@ export class SettingsPage extends PreferencesPage {
|
||||
type: "s",
|
||||
bind: "dnd-center-layout",
|
||||
items: [
|
||||
{ id: "swap", name: _("Swap") },
|
||||
{ id: "tabbed", name: _("Tabbed") },
|
||||
{ id: "stacked", name: _("Stacked") },
|
||||
],
|
||||
@ -129,6 +130,19 @@ export class SettingsPage extends PreferencesPage {
|
||||
],
|
||||
});
|
||||
|
||||
this.add_group({
|
||||
title: _("Behavior"),
|
||||
children: [
|
||||
new SwitchRow({
|
||||
title: _("Move Pointer with the Focus"),
|
||||
subtitle: _("Move the pointer when focusing or swapping via keyboard"),
|
||||
experimental: true,
|
||||
settings,
|
||||
bind: "move-pointer-focus-enabled",
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
if (!production) {
|
||||
this.add_group({
|
||||
title: _("Logger"),
|
||||
|
||||
Reference in New Issue
Block a user