I am working on an extension to add coloured borders to a window based on the window.
I am adding St.Bin to the global.window_group and giving the St.Bin a style using css.
Everything working fine and the borders are drawn on the window. However, when drawing multiple borders all the borders seems to be on top of all the windows. The borders doesn’t be have as normal windows.
As the screenshot shows the overlap between the added borders. I am asking if there are a better way to implement this!!
My code is below
extensions.js
const { GObject, St, Meta, GLib } = imports.gi;
const Main = imports.ui.main;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const Window = Me.imports.window;
class Extension {
constructor(uuid) {
this._uuid = uuid;
this.windows = {}
}
windowCreated(display, window) {
log("Window Created")
this.windows[window.get_description()] = new Window.Window(window)
}
enable() {
log("Enabled")
this.windowCreatedID = global.display.connect('window-created', this.windowCreated.bind(this))
}
disable() {
log("Disabled")
for (let windowKey in this.windows){
this.windows[windowKey].windowClosed()
global.window_group.remove_child(this.windows[windowKey].border)
delete this.windows[windowKey]
}
global.display.disconnect(this.windowCreatedID)
}
}
function init(meta) {
return new Extension(meta.uuid);
}
window.js
const { GObject, St } = imports.gi;
const BORDERSIZE = 3;
class Window{
constructor(window){
this.window = window
//this.workspaceChangedID = this.window.connect('workspace-changed', this.windowClosed.bind(this))
this.sizeChangedID = this.window.connect('size-changed', this.updateBorderLayout.bind(this))
this.positionChangedID = this.window.connect('position-changed', this.updateBorderLayout.bind(this))
this.border = new St.Bin({
style_class: 'border',
reactive: true,
can_focus: true,
track_hover: true,
});
global.window_group.add_child(this.border)
let rect = this.window.get_frame_rect()
this.border.set_position(rect.x, rect.y)
this.border.set_size(rect.width + BORDERSIZE, rect.height+ BORDERSIZE)
this.isNewWindow = true
}
updateBorderLayout(){
log("Update Window Border")
let rect = this.window.get_frame_rect()
this.border.set_position(rect.x, rect.y)
this.border.set_size(rect.width + BORDERSIZE, rect.height + BORDERSIZE)
}
windowClosed(){
log("Window Closed")
log("Window ID = "+this.window.get_description())
log("workspace-changed ID = "+this.workspaceChangedID)
log("size-changed ID = "+this.sizeChangedID)
log("position-changed ID = "+this.positionChangedID)
this.window.disconnect(this.workspaceChangedID)
this.window.disconnect(this.sizeChangeID)
this.window.disconnect(this.positionChangedID)
}
}
stylesheet.css
/* Add your custom extension styling here */
.border {
border-style: solid;
border-color: #FFAD00;
border-radius: 5px;
box-shadow: inset 0 0 0 1px rgba(200, 200, 200, 0);
border-width: 3px;
}
fmuellner
(Florian Müllner)
July 21, 2022, 2:51pm
2
However, when drawing multiple borders all the borders seems to be on top of all the windows. The borders doesn’t be have as normal windows.
Well yes. That’s because the borders aren’t actually windows. The compositor has no idea where to put them in the stack, so ignores them.
You have to move them to the right layer yourself, and connect to the global.display('restacked')
signal to update them.
I am new to the gnome development. So if you could provide me with an example or a source that I could use to solve it?
Nevermind, your comment was more than enough to solve the problem thank you!
The new code
extension.js
const { GObject, St, Meta, GLib } = imports.gi;
const Main = imports.ui.main;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const Window = Me.imports.window;
class Extension {
constructor(uuid) {
this._uuid = uuid;
this.winCreatedHandlerID = null
this.restackHandlerID = null
this.windows = {}
}
windowCreated(display, metaWindow) {
log("Window Created")
this.windows[metaWindow.get_description()] = new Window.Window(metaWindow)
}
restack(display){
global.window_group.get_children().forEach(
(child) => {
let metaWindow = this.checkMetaWindow(child)
if (!metaWindow) return;
let window = this.windows[metaWindow.get_description()]
global.window_group.set_child_above_sibling(window.border, child)
}
)
}
checkMetaWindow(child){
let metaWindow = null
try {
metaWindow = child.get_meta_window()
} catch (error) {
log(error)
}
if(!metaWindow) return false;
let type = metaWindow.get_window_type()
if (
type != Meta.WindowType.NORMAL &&
type != Meta.WindowType.DIALOG &&
type != Meta.WindowType.MODAL_DIALOG
) return false;
return metaWindow
}
enable() {
log("Enabled")
this.winCreatedHandlerID = global.display.connect('window-created', this.windowCreated.bind(this))
this.restackHandlerID = global.display.connect('restacked', this.restack.bind(this))
global.window_group.get_children().forEach(
(child) => {
let metaWindow = this.checkMetaWindow(child)
if (!metaWindow) return;
log(Window.Window)
let window = new Window.Window(metaWindow)
this.windows[metaWindow.get_description()] = window
global.window_group.add_child(window.border)
global.window_group.set_child_above_sibling(window.border, child)
}
)
}
disable() {
log("Disabled")
for (let windowKey in this.windows){
this.windows[windowKey].windowClosed()
global.window_group.remove_child(this.windows[windowKey].border)
delete this.windows[windowKey]
}
global.display.disconnect(this.winCreatedHandlerID)
global.display.disconnect(this.restackHandlerID)
}
}
function init(meta) {
return new Extension(meta.uuid);
}
window.js
const { GObject, St } = imports.gi;
const BORDERSIZE = 3;
class Window{
constructor(metaWindow){
this.metaWindow = metaWindow
this.border = new St.Bin({style_class: 'border'});
let rect = this.metaWindow.get_frame_rect()
this.border.set_position(rect.x, rect.y)
this.border.set_size(rect.width + BORDERSIZE, rect.height+ BORDERSIZE)
this.sizeChangedID = this.metaWindow.connect('size-changed', this.updateBorderLayout.bind(this))
this.positionChangedID = this.metaWindow.connect('position-changed', this.updateBorderLayout.bind(this))
}
updateBorderLayout(){
log("Update Window Border")
let rect = this.metaWindow.get_frame_rect()
this.border.set_position(rect.x, rect.y)
this.border.set_size(rect.width + BORDERSIZE, rect.height + BORDERSIZE)
}
windowClosed(){
log("Window Closed")
log("Window ID = "+this.metaWindow.get_description())
log("workspace-changed ID = "+this.workspaceChangedID)
log("size-changed ID = "+this.sizeChangedID)
log("position-changed ID = "+this.positionChangedID)
this.metaWindow.disconnect(this.workspaceChangedID)
this.metaWindow.disconnect(this.sizeChangeID)
this.metaWindow.disconnect(this.positionChangedID)
}
}
system
(system)
Closed
August 21, 2022, 2:37pm
5
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.