How when I start a new disposable (dispxxxx) qubes from a specific appvm, I can configure devilspie2 to make it so it goes into a specific workspace ?
Here’s a general guide:
You need to know what devilspie2 “sees”.
You can do this by creating a file in ~/.config/devilspie2/debug.lua
:
debug_print("Application: " .. get_application_name())
debug_print("Window: " .. get_window_name());
Then run devilspie2 --debug
in a dom0 terminal
When you open a disposableVM you will see the Application and Window
names - [dispxxxxx] Mozilla Firefox
for example.
And now you hit a major problem - I don’t think there is a distinguishing
feature for qubes launched from a specific appvm.
The only thing that might work would be to use a named disposableVM
for that qube, and then you could match against that name to move any
windows to a specific workspace.
if string.match(get_window_name(), "[name_of_namedDisposable]") then
set_windows_workspace(2);
end
If you did this, then I would suggest using the qubes-idle package
configured with a short timeout to automatically close the named
disposableVM when you close a window.
qube = get_window_property("_QUBES_VMNAME");
ws = 0;
local function compare(t, s, n)
if n==1
then return t:sub(n, s:len())==s;
else return t:sub(-s:len())==s;
end
end
if compare(qube, “disp”, 1) then ws = 2
if (ws > 0) then
set_window_workspace(ws);
change_workspace(ws);
end
… there is probably also a windows property other then the VM name
that will tell you whether it’s a DispVM. Worth looking into.
/Sven
See also: Autostart program in specific workspace and Open application in specific workspace (xfce).
Yes you are right it’s easier to use a named disposableVM instead, it’s working perfectly fine
Thanks
I don’t undersand this part, what is this doing ?
I didn’t find a list of proprieties that could help in any documentation, so I looked in the code and found this list of variable : qubes-gui-daemon/gui-daemon/xside.c at a6bbe5309d15848d3cf244c8655ffd428de6c3ee · QubesOS/qubes-gui-daemon · GitHub
atoms_to_intern[] = {
{ &g->tray_selection, tray_sel_atom_name },
{ &g->tray_opcode, "_NET_SYSTEM_TRAY_OPCODE" },
{ &g->xembed_message, "_XEMBED" },
{ &g->xembed_info, "_XEMBED_INFO" },
{ &g->wm_state, "_NET_WM_STATE" },
{ &g->wm_state_fullscreen, "_NET_WM_STATE_FULLSCREEN" },
{ &g->wm_state_demands_attention, "_NET_WM_STATE_DEMANDS_ATTENTION" },
{ &g->wm_state_hidden, "_NET_WM_STATE_HIDDEN" },
{ &g->wm_workarea, "_NET_WORKAREA" },
{ &g->frame_extents, "_NET_FRAME_EXTENTS" },
{ &g->wm_state_maximized_vert, "_NET_WM_STATE_MAXIMIZED_VERT" },
{ &g->wm_state_maximized_horz, "_NET_WM_STATE_MAXIMIZED_HORZ" },
{ &g->qubes_label, "_QUBES_LABEL" },
{ &g->qubes_label_color, "_QUBES_LABEL_COLOR" },
{ &g->qubes_vmname, "_QUBES_VMNAME" },
{ &g->qubes_vmwindowid, "_QUBES_VMWINDOWID" },
{ &g->net_wm_icon, "_NET_WM_ICON" },
{ &g->wm_current_desktop, "_NET_CURRENT_DESKTOP" },
{ &g->wmDeleteMessage, "WM_DELETE_WINDOW" },
And tried different things like :
domainn = get_window_property('_QUBES_VMWINDOWID');
debug_print(domainn)
domainnn = get_window_property('_QUBES_LABEL_COLOR');
debug_print(domainnn)
domain = get_window_property('_QUBES_VMNAME');
debug_print(domain)
and so on, but none of them seems usefull
I don’t understand this part, what is this doing ?
If n=0 it is comparing the end of t to s and if n=1 it is comparing the
beginning of t to s
So:
compare(“disp1234”, “disp”, 1) returns true
compare(“work-web”, “web”, 0) returns true
See also the
String.sub
explanation.
So t:sub(n, s:len()) returns the part of t that starts at letter n and
is s:len() letters long. s:len() returns the length of s.
t:sub(-s:len()) returns the last s:len() letters/characters of t.
And tried different things like: and so on, but none of them seems useful
I was hoping for someone like @unman to come and drop a nugget of
knowledge. But he already answered that there is no other way and you
even checked the code (nice!). So I guess this was a dead end.
So I found a little solution to move a dispxxxx window depending of his template to a specific workspace with devilspie2 with this config :
if (get_window_type() ~= "WINDOW_TYPE_NORMAL") then
return
end
-- change these to customize
workspaceAssociation = {};
workspaceAssociation["vault"] = 1;
workspaceAssociation["dom0"] = 33;
-- dispVM
workspaceAssociation["whonix-ws-15-dvm"] = 2;
domain = get_window_property('_QUBES_VMNAME');
if (domain == "") then
domain = "dom0";
elseif (string.find(string.lower(domain), "disp")) then
amazingCommand = "sudo qvm-ls|grep " .. domain .. " | tr -s ' ' | cut -d ' ' -f 5'"
local handle = io.popen(amazingCommand)
result = handle:read("*a")
result = result:sub(1, -2)
handle:close()
debug_print("This is a dispVM : " .. domain .. " with the following template " .. result)
domain = result;
end
if (workspaceAssociation[domain] ~= nil and workspaceAssociation[domain] > 0) then
if (workspaceAssociation[domain] <= get_workspace_count()) then
set_window_workspace(workspaceAssociation[domain])
debug_print("Moving ".. get_application_name() .." to workspace ".. workspaceAssociation[domain] .."\n\n")
end
endqube = get_window_property("_QUBES_VMNAME");
ws = 0;
end
With the name of a disposable VM with dispxxxx, I use qvm-ls to know his template, and from there I can specify in which workspace I want it to be in.
With the name of a disposable VM with dispxxxx, I use qvm-ls to know
his template, and from there I can specify in which workspace I want
it to be in.
Excellent!