[Solved] Linux Workspace 2-4

Post

Posted
Rating:
#1 (In Topic #915)
Enthusiast
AndyGable is in the usergroup ‘Enthusiast’
 Hi Everyone

Is it possible to have a application start on Workspace 1 but move it to another workspace ?

For example my main workspace (workspace 1 on Debian) is where I work on my code but when the app starts i would like it to show in Workspace 2 (the 4 little boxes at the bottom of the screen in Debian linux)

The Idea is I want to load some background apps but have thier windows display on other workspace and keep the main workspace clear

can I do this with Gambas or do I have to load each program I want in each workspace?
Online now: No Back to the top

Post

Posted
Rating:
#2
Guru
BruceSteers is in the usergroup ‘Guru’
I believe you can use Form.Move()

The workspaces are calculated as one big desktop.
So to open the form at x ,y position 100, 100 on a workspace to the right of the main screen do this…

Code (gambas)

  1. MyForm.Move(Screen.Width + 100, 100)
  2. MyForm.Show
  3.  
Online now: No Back to the top

Post

Posted
Rating:
#3
Guru
BruceSteers is in the usergroup ‘Guru’

BruceSteers said

I believe you can use Form.Move()

The workspaces are calculated as one big desktop.
So to open the form at x ,y position 100, 100 on a workspace to the right of the main screen do this…

Code (gambas)

  1. MyForm.Move(Screen.Width + 100, 100)
  2. MyForm.Show
  3.  

Darn my apologies, that does not seem to work :(

I read this reply from Benoit on stack overflow gambas - GAMBAS3 - show form on second screen - Stack Overflow
Although he is talking about screens there not virtual desktops.
Online now: No Back to the top

Post

Posted
Rating:
#4
Guru
BruceSteers is in the usergroup ‘Guru’
I found a way that works…

this way moves the current active window to workspace to the right of the current one.

Code (gambas)

  1.   X11.MoveWindow(X11.ActiveWindow, Screen.W + 100, Me.Top)
  2.  

Or this for a specific window…

Code (gambas)

  1.  
  2. Public Sub btn2_Click()
  3.  
  4.   Form2.Show
  5.   Dim iActiv As Integer = X11.ActiveWindow ' for some reason if you do not use this line the next line crashes gambas
  6.  
  7.   X11.MoveWindow(Form2.Id, Screen.W + Form2.X, form2.Top)
  8.  
  9.  
  10.  
  11.  


Requires the gb.desktop.x11 component
Online now: No Back to the top

Post

Posted
Rating:
#5
Guru
BruceSteers is in the usergroup ‘Guru’
Also this works…  (also needs gb.desktop.x11)

Code (gambas)

  1. Public Sub btnMoveWindowToRightWorkspace_Click()
  2.  
  3.   Form2.Show
  4.   Dim dw As DesktopWindow = New DesktopWindow(Form2.Id)
  5.   if Desktop.Type = "MATE" Then dw.Move(Screen.W + Form2.X, Form2.Top) Else dw.Desktop +=1
  6.  
  7.  
  8.  


and note. this will most definitely NOT work on wayland,  it's x11 only.
Online now: No Back to the top

Post

Posted
Rating:
#6
Guru
BruceSteers is in the usergroup ‘Guru’
This has been interesting.

I made a class file..
It's in my project .src called Form.class

EDITED:

Code (gambas)

  1. ' Gambas class file
  2. ' with file name Form.class in your .src folder this adds workspace shifting to ALL Forms
  3. ' Requires gb.desktop.x11
  4.  
  5.  
  6. Public Enum Move_Left, Move_Right, Move_Up, Move_Down
  7.  
  8. Public Sub MoveToWorkSpace((Direction) As Integer, Optional Follow As Boolean)
  9.  
  10.   Dim xw As DesktopWindow = New DesktopWindow(Me.Handle)
  11.  
  12.   Select Direction
  13.  
  14.     Case Move_Right
  15.       If Desktop.Type = "MATE" Then xw.Move(Screen.Width + Me.X, Me.Top) Else xw.Desktop += 1
  16.  
  17.     Case Move_Left
  18.       If Desktop.Type = "MATE" Then xw.Move(0 - Screen.Width + Me.X, Me.Top) Else xw.Desktop = Max(xw.Desktop - 1, 0)
  19.     ' Note, setting Desktop to -1 makes the window sticky (shows on all workspaces) so we limit to 0
  20.  
  21.  
  22.    If Follow Then
  23.     If Desktop.Type = "MATE" Then
  24.       Me.Activate
  25.     Else
  26.       X11.CurrentDesktop = If(Direction = Move_Right, X11.CurrentDesktop + 1, Max(X11.CurrentDesktop - 1, 0))
  27.     Endif
  28.  
  29.  
  30.  

This saved as Form.class adds workspace switching to all and any of my Forms :)

So my app can now do this with menu items to shift the window left or right…

Code (gambas)

  1.  
  2. Public Sub mnuWorkspaceLeft_Click()
  3.  
  4.   FMain.MoveToWorkSpace(Form.Move_Left, True)
  5.  
  6.  
  7. Public Sub mnuWorkspaceRight_Click()
  8.  
  9.   FMain.MoveToWorkSpace(Form.Move_Right, True)
  10.  
  11.  

PS. the Follow boolean option toggles between moving a window to a workspace and staying on the current workspace or switching workspace with it.
Online now: No Back to the top

Post

Posted
Rating:
#7
Guru
BruceSteers is in the usergroup ‘Guru’
I tested this on other desktops like gnome and cinnamon and find it does not really work on anything except MATE desktop.
 :(

this was because i found setting the X11.DesktopWindow.Desktop property did not make the window switch workspace ,, on MATE , but turns out it does on gnome and cinnamon.

So i have modified the above code to make moving left or right work on the other desktops.
making up and down work involves a bit more code and getting info about the layout that i have not got working yet.
Online now: No Back to the top

Post

Posted
Rating:
#8
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
I have tried it in KDE and the window moves but is not visible on the new desktop.  :x

I have not tried the new code…. yet.

new code makes it work  :D

but it does not follow .
Online now: No Back to the top

Post

Posted
Rating:
#9
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
 it will only move if there is already a desktop open in the direction of the move … it does not create a desktop.

And it will follow if there is an open program on the new desktop.
Online now: No Back to the top

Post

Posted
Rating:
#10
Avatar
Guru
cogier is in the usergroup ‘Guru’
I use Linux Mint 20.3 with the Cinnamon desktop.

I could not get Gambas to do what was wanted, so I took a different tack. I have no idea if it will work in your distro, but here are my efforts.

<VIDEO content="https://www.cogier.com/video/MoveWorkspaces.webm">[video]
[/video]</VIDEO>

<IMG src="https://www.cogier.com/gambas/MoveWorkspaces.png"> </IMG>

Run the following code in a Graphical Application

Code (gambas)

  1. ' Gambas class file
  2.  
  3. CheckBox1 As CheckBox
  4. $iCurrentWS As Integer      'Stores the current workspace
  5. AllButtons As New Button[]  'Keeps an array of all the Buttons
  6.  
  7. Public Sub Form_Open()
  8.  
  9.   Dim iGet As Integer[] = GetWorkSpaces()
  10.  
  11.   $iCurrentWS = iGet[1]
  12.   BuildForm
  13.   SetCurrentButton
  14.  
  15.  
  16. Public Sub Buttons_Click() 'Triggered when any of the buttons are clicked
  17.  
  18.   MoveToWorkspace(Last.Tag, CheckBox1.Value)
  19.   $iCurrentWS = Last.Tag
  20.   SetCurrentButton
  21.  
  22.  
  23. Public Sub SetCurrentButton() 'This disables the current workspace button
  24.  
  25.   Action["Enable"].Enabled = True
  26.   AllButtons[$iCurrentWS].Enabled = False
  27.  
  28.  
  29. Public Sub MoveToWorkspace(Workspace As Integer, Optional DontFollow As Boolean) 'This moves the program
  30.  
  31.   If DontFollow = True Then
  32.     Shell "wmctrl -r :ACTIVE: -t " & Str(Workspace)
  33.   Else
  34.     Shell "wmctrl -r :ACTIVE: -t " & Str(Workspace) & "; wmctrl -s " & Str(Workspace)
  35.  
  36.  
  37. Public Sub GetWorkSpaces() As Integer[] 'This gets the number of Workspaces available
  38.  
  39.   Dim sWPlaces As String
  40.   Dim sWorkPlaces As String[]
  41.   Dim iLoop, iCurrent As Integer
  42.  
  43.   Shell "wmctrl -d" To sWPlaces
  44.   sWorkPlaces = Split(sWPlaces, gb.newline, "", True)
  45.  
  46.   For iLoop = 0 To sWorkPlaces.Max
  47.     If InStr(sWorkPlaces[iLoop], "*") > 0 Then iCurrent = iLoop
  48.   Next
  49.  
  50.   Return [sWorkPlaces.Max, iCurrent]
  51.  
  52.  
  53. Public Sub BuildForm() 'This puts all the objects needed on the form
  54.  
  55.   Dim hButton As Button
  56.   Dim VBox1 As VBox
  57.   Dim pPanel As Panel
  58.   Dim iLoop As Integer
  59.   Dim iGet As Integer[] = GetWorkSpaces()
  60.   Dim sWS As Integer = iGet[0]
  61.  
  62.   With Me
  63.     .Height = 400
  64.     .Width = 200
  65.     .Padding = 5
  66.     .Arrangement = Arrange.Vertical
  67.     .Title = "Move me!"
  68.     .Center
  69.  
  70.   With VBox1 = New VBox(Me) As "VBox1"
  71.     .height = 300
  72.     .Width = 100
  73.     .Expand = True
  74.  
  75.   With CheckBox1 = New CheckBox(VBox1) As "CheckBox1"
  76.     .Text = "Don't follow me."
  77.     .ToolTip = "If checked the program will move by you wont!"
  78.     .Value = False
  79.  
  80.   For iLoop = 0 To sWs
  81.     With pPanel = New Panel(VBox1)
  82.       .Height = 7
  83.     End With
  84.     With hButton = New Button(VBox1) As "Buttons"
  85.       .Height = 28
  86.       .Width = 100
  87.       .Text = "Move me to Workspace " & Str(iLoop)
  88.       .Tag = iLoop
  89.       .Action = "Enable"
  90.     End With
  91.     AllButtons.Add(hButton)
  92.   Next
  93.  
Online now: No Back to the top

Post

Posted
Rating:
#11
Guru
BruceSteers is in the usergroup ‘Guru’
fixed following on gnome/cinnamon/kde with this..

Code (gambas)

  1. Public Sub ShiftWorkSpace((Direction) As Integer, Optional Follow As Boolean)
  2.  
  3.   Dim xw As DesktopWindow = New DesktopWindow(Me.Handle)
  4.  
  5.   Select Direction
  6.     Case Move_Right
  7.       If Desktop.Type = "MATE" Then xw.Move(Screen.Width + Me.X, Me.Top) Else xw.Desktop += 1
  8.     Case Move_Left
  9.       If Desktop.Type = "MATE" Then xw.Move(0 - Screen.Width + Me.X, Me.Top) Else xw.Desktop = Max(xw.Desktop - 1, 0)
  10.  
  11.   If Follow Then
  12.     If Desktop.Type = "MATE" Then
  13.       Me.Activate
  14.     Else
  15.       X11.CurrentDesktop = If(Direction = Move_Right, X11.CurrentDesktop + 1, Max(X11.CurrentDesktop - 1, 0))
  16.     Endif
  17.  
  18.  
  19.  

seems MATE works differently to everything else :-\
Online now: No Back to the top

Post

Posted
Rating:
#12
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
 That work fine on my  Kubuntu
Online now: No Back to the top

Post

Posted
Rating:
#13
Guru
BruceSteers is in the usergroup ‘Guru’
Right then i have done this work…

BruceS on gambas M/L said

From what I've seen there are 2 ways of implementing virtual desktops with the window managers, one involves multiple viewports and one is one large screen. ( Non-ICCCM features | Extended Window Manager Hints / Implementation note)

It seems gb.desktop.x11 is coded to handle the multiple desktops method but not the single big screen virtual type :(

I'm almost there with implementing this (see attached project)

the project contains a folder called X11LargeDesktop containing files that add the following to gb.desktop.x11 according to infomation i got from here Root Window Properties (and Related Messages) | Extended Window Manager Hints

X11.DesktopCount and X11.CurrentDesktop now works for large desktops.

DesktopWindow.Desktop now also works for large desktops.

X11.IsLargeDesktop True if large desktop false if multiple viewports.

X11.ViewPorts returns a list of the viewport positions if using large desktop taking Orientation into account. Still todo: handle start corners, currently assumes TopLeft.

X11.Supported As String[], returns a list of the supported wm commands (from hint _NET_SUPPORTED)

X11.GetDesktopNames(DefaultName as String="Workspace") , get's the desktop names or makes them up if not found.


attached is a test app using the above features that has one window that will move to a desktop or change the amount of desktops and another window that will move itself to other desktops.

Adding the X11LargeDesktop folder to your own projects .src folder will automatically enable desktop switching on systems the current gb.desktop.x11 does not support.


<COLOR color="#33CC33">This is better than any of the previous code i have shown that uses
If Desktop.Type = "MATE"
as this uses the proper x11 hint to tell if the window manager is large desktop or multiple viewports. , it is possible to use alternative window managers on MATE so the attached project is much better.
</COLOR>


I've forwarded this code to the gambas M/L and Ben says he'll take a look so hopefully gambas will get the update (re-coded to perfection by Benoit of course) , it's probably just something he didn't know about but as i have paved the way and done some of the groundwork I'll bet he'll accept that handling the "other" desktop method gb.desktop.x11 does not yet support will be a good thing :)

(see below for code)
Online now: No Back to the top

Post

Posted
Rating:
#14
Guru
BruceSteers is in the usergroup ‘Guru’
Update for what it's worth..

updates include..
handling for multiple row/column in VirtualRoot desktops taking into account the Orientation, Rows, Columns and the annoying StartCorner properties

Notes: the only desktop i have that uses a VritualRoot is MATE on Mint using compiz and setting multiple rows works in the test app (compiz "desktop cube" has to be disabled and "desktop wall" enabled)

Changing rows/columns works for virtualroot desktops not for multiple viewports

A much better check to see if desktop type is multiple vieports or a virtualroot is done.

I changed the format a bit by making a DesktopRoot.class for VirtualRoot screen handling and 2 functions to get the desktop index from the viewport position (GetIndex([X,Y])) and vice versa get the viewport at ( [X, Y] = DesktopRoot[Index]).

Working out the indexes from the viewport positions and vice versa when start corner is not TopLeft was quite a brain ache.

My head hurts :(

EDIT:
I uploaded a new version 0.0.12
I forgot to check using Vertical mode with the desktop workspace switcher and hadn't handled it yet (fixed now)

I made the test app hide the Row/Column changer if not showing a virtual root as changing it does not work.

Download is now here
Online now: No Back to the top

Post

Posted
Rating:
#15
Enthusiast
AndyGable is in the usergroup ‘Enthusiast’
 Hi everyone sorry for being so silent on this I've been super unwell.

Thank you for all the recommendations I'm planning to use this to have all my add on modules on one workspace (workspace 2) and my main application on workspace 1

I am using xfce on Debian 11 now I'm feeling a bit more human I will see about implementing some of the options you all have come up with.


Thanks once again and I am so sorry for not being around on this one for a while.
Online now: No Back to the top

Post

Posted
Rating:
#16
Enthusiast
AndyGable is in the usergroup ‘Enthusiast’

BruceSteers said

I found a way that works…

this way moves the current active window to workspace to the right of the current one.

Code (gambas)

  1.   X11.MoveWindow(X11.ActiveWindow, Screen.W + 100, Me.Top)
  2.  

Or this for a specific window…

Code (gambas)

  1.  
  2. Public Sub btn2_Click()
  3.  
  4.   Form2.Show
  5.   Dim iActiv As Integer = X11.ActiveWindow ' for some reason if you do not use this line the next line crashes gambas
  6.  
  7.   X11.MoveWindow(Form2.Id, Screen.W + Form2.X, form2.Top)
  8.  
  9.  
  10.  
  11.  


Requires the gb.desktop.x11 component


I assume this would be the code I need though to move my customer display application to the second monitor on my Debian machine (extended desktop to it)
Online now: No Back to the top

Post

Posted
Rating:
#17
Guru
BruceSteers is in the usergroup ‘Guru’

AndyGable said

BruceSteers said

I found a way that works…

this way moves the current active window to workspace to the right of the current one.

Code (gambas)

  1.   X11.MoveWindow(X11.ActiveWindow, Screen.W + 100, Me.Top)
  2.  

Or this for a specific window…

Code (gambas)

  1.  
  2. Public Sub btn2_Click()
  3.  
  4.   Form2.Show
  5.   Dim iActiv As Integer = X11.ActiveWindow ' for some reason if you do not use this line the next line crashes gambas
  6.  
  7.   X11.MoveWindow(Form2.Id, Screen.W + Form2.X, form2.Top)
  8.  
  9.  
  10.  
  11.  


Requires the gb.desktop.x11 component


I assume this would be the code I need though to move my customer display application to the second monitor on my Debian machine (extended desktop to it)

Then you assume incorrectly I'm afraid. another screen is not the same as a workspace.

All the later code I provided was for dealing with workspace changing.

2 monitors should show as a single large area.
You will have to look and move the window accordingly.
Form1.Move() will probably do. No x11 needed.
Online now: No Back to the top

Post

Posted
Rating:
#18
Enthusiast
AndyGable is in the usergroup ‘Enthusiast’

BruceSteers said

I believe you can use Form.Move()

The workspaces are calculated as one big desktop.
So to open the form at x ,y position 100, 100 on a workspace to the right of the main screen do this…

Code (gambas)

  1. MyForm.Move(Screen.Width + 100, 100)
  2. MyForm.Show
  3.  

Sorry my bad it should have been this one
Online now: No Back to the top

Post

Posted
Rating:
#19
Guru
BruceSteers is in the usergroup ‘Guru’

AndyGable said

Hi everyone sorry for being so silent on this I've been super unwell.

Thank you for all the recommendations I'm planning to use this to have all my add on modules on one workspace (workspace 2) and my main application on workspace 1

I am using xfce on Debian 11 now I'm feeling a bit more human I will see about implementing some of the options you all have come up with.


Thanks once again and I am so sorry for not being around on this one for a while.

All okay fella, glad you're getting better.

I found it all quite enlightening.
i had tried to use the x11 desktop commands to switch workspaces before but it never did anything for me so i thought i was mistaken about something.
with this puzzle i found out it was because i use compiz.
but then i found the workaround :)

if you do not use compiz then you should be able to use X11.DesktopCount / X11.CurrentDesktop without any of the classes i provided, they only fix the desktop.x11 methods on compiz
Online now: No Back to the top

Post

Posted
Rating:
#20
Guru
BruceSteers is in the usergroup ‘Guru’
For physical screens i found the following…

If the main primary display is to the right of the other display then Screen.X will not show as 0 it will show as the left hand screen width.

That could be useful but if the main display is to the left then Screen.class just shows X as 0 and width as the current display width not the overall size.

you may be able to read _GTK_WORKAREAS_D0

in terminal..
<HIGHLIGHT highlight="shell">
$ xprop -root -notype _GTK_WORKAREAS_D0
</HIGHLIGHT>

in gambas

Code (gambas)

  1. Dim aDims as Integer[] = X11.GetWindowProperty(X11.RootWindow, "_GTK_WORKAREAS_D0")
  2.  

That will give you info about both displays and their positions, the primary display is the 1st 4 numbers, then next 4 will be the secondary display if there.
you should be able to control positioning from there.
(workareas do not show the total screen size just the "usable" area like Screen.AvailableX, Screen.AvailableWidth, etc)
Online now: No Back to the top

Post

Posted
Rating:
#21
Enthusiast
AndyGable is in the usergroup ‘Enthusiast’
 Cool

thank you for the information

would there be a reason why when I have FMain.hide or FMain.visible = false the form is still shown

is the first form hide status ignored in Gambas?
Online now: No Back to the top

Post

Posted
Rating:
#22
Guru
BruceSteers is in the usergroup ‘Guru’
Okay for screens use something like this…

Code (gambas)

  1.  
  2. Public Sub GoToScreen(iOpenOn As Integer)
  3.  
  4.   Me.Left = ((Screens[iOpenOn].W - Me.W) / 2) + Screens[iOpenOn].X
  5.   Me.Top = ((Screens[iOpenOn].H - Me.H) / 2) + Screens[iOpenOn].Y
  6.  
  7.  
  8.  

that will jump to the selected display center screen.

and you can use Me.Window.Screen to detect the display you are currently on but it does not work until the application has loaded (not in Form_Open or Form_Show)

Screens[0] is primary Screens[1] secondary
Online now: No Back to the top

Post

Posted
Rating:
#23
Guru
BruceSteers is in the usergroup ‘Guru’

AndyGable said

Cool

thank you for the information

would there be a reason why when I have FMain.hide or FMain.visible = false the form is still shown

is the first form hide status ignored in Gambas?


Without seeing the code it's impossible to guess, but to answer the question, no,  the main form is not restricted from hiding.

Code (gambas)

  1.  
  2. Public Sub btnHideMe_Click()
  3.  
  4.   Me.Hide
  5.   Wait 3
  6.   Me.show
  7.  
  8.  
  9.  

If i do that my window hides then pops back 3 seconds later even without Persistent set true.
So it's your code somewhere either preventing the window closing or opening it again.

Is there a check to stop the form closing in Form_Close? (setting Persistent should fix that)
a LostFocus() event could be triggered, do you have one regaining focus?.
a .SetFocus()  or .Activate() or .EnsureVisible call could cause form to re-show.
Online now: No Back to the top

Post

Posted
Rating:
#24
Guru
BruceSteers is in the usergroup ‘Guru’
okay so now i have this app….

like before the workspace switching functions but they have been fixed to work with multiple displays.
if more than one monitor my size calculations were incorrect.

Added a class called it BigScreen
BigScreen.Width
BigScreen.Height


Will show the total screen size including both monitors if there are 2, this fixes my previous code.

also now the test app has a screen switching option as well as workspace switching.

It may require some debugging on systems i've not tested it on.

Best wishes

Attachment
Online now: No Back to the top

Post

Posted
Rating:
#25
Guru
BruceSteers is in the usergroup ‘Guru’
Here's a little Workspace switcher i just made…

It has some updates/fixes to the classes in the above mentioned project.

It's set to work on a System tray icon but the code could probably be easily made to pop open the window via a button in your own project to visually switch workspaces.

I've tried to make it show windows on other workspaces in the selection window while the preview for the current desktop is a screenshot.

Enjoy :)

Attachment
Online now: No Back to the top
1 guest and 0 members have just viewed this.