Hi All !
The basic idea, is that at any given time I may have some VMs running in background / Server mode on my workstation, without consuming precious desktop taskbar space, and wanna bring them back into desktop mode later.
While tinkering around with code, I came across interesting X11 feature - Map/Unmap, and immediately recalled -- Wish #6798.
I wrote a patch to exploit this feature on X11 / Linux hosts.
MIT licensed. (as always)
----------------------
update: Klaus, VirtualBox developer, realized the need, but disagrees with the approach. He thinks it needs to be done deeply in the main API, instead of GUI, so patch was rejected.
Besides, it does not work with multi-monitor VMs.
I decided to put it here, in the hope people will find it useful.
UPDATE: Found sister project: RBTray
http://rbtray.sourceforge.net/
--
-Alexey Eromenko "Technologov"
[PATCH] hide VBox VM from desktop taskbar
-
- Volunteer
- Posts: 3342
- Joined: 10. May 2007, 16:59
- Location: Israel
[PATCH] hide VBox VM from desktop taskbar
- Attachments
-
- vbox-gui-X11-window-hide.zip
- PATCH - should be applied vs 4.1.0 code
- (3.13 KiB) Downloaded 142 times
-
- Volunteer
- Posts: 3342
- Joined: 10. May 2007, 16:59
- Location: Israel
Re: [PATCH] hide VBox VM from desktop taskbar
+ Windows hosts support:
... multi-monitor VMs don't work this way...
Code: Select all
bool VBoxGlobal::hideWindow (WId aWId)
...
#if defined (Q_WS_WIN32)
+result &= !!ShowWindow (aWId, SW_HIDE);
Which is the last hint that the approach you're using is a hack which won't do the job in the general case.
The proper solution would be to have a generic window manipulation method which at the same time eliminates the need for having any "window id" information in the API. This was always considered a hack, but we didn't have time to clean it up. Adding more hacks won't be accepted.
One way would be a IDisplay::manipulateWindow(enum WindowOp) method - which can hide/unhide/bring to front/detach/attach/... operations. The association with IDisplay means that it'd always work on all screens associated with a multi-monitor VM. If there's need to make this per screen it simply needs to be moved to IFramebuffer.
This would at the same time allow putting the totally misplaced IMachine::showConsoleWindow method in the context where it should be... it always was performed by the VM process.
Klaus
-
- Site Moderator
- Posts: 34369
- Joined: 6. Sep 2008, 22:55
- Primary OS: Linux other
- VBox Version: OSE self-compiled
- Guest OSses: *NIX
Re: [PATCH] hide VBox VM from desktop taskbar
In Linux you can already start the VM headless without leaving a terminal window open. (nohup)
So Is this for the GUI manager? and does it enable/disable while running?
So Is this for the GUI manager? and does it enable/disable while running?
-
- Volunteer
- Posts: 3342
- Joined: 10. May 2007, 16:59
- Location: Israel
Re: [PATCH] hide VBox VM from desktop taskbar
VBoxheadless is *far* from comfortable. Not user-friendly.
>So Is this for the GUI manager? and does it enable/disable while running?
Yes, my way is super-user-friendly and very fast. Just right-lick on VM hide/show buttons.
>So Is this for the GUI manager? and does it enable/disable while running?
Yes, my way is super-user-friendly and very fast. Just right-lick on VM hide/show buttons.
-
- Site Moderator
- Posts: 34369
- Joined: 6. Sep 2008, 22:55
- Primary OS: Linux other
- VBox Version: OSE self-compiled
- Guest OSses: *NIX
Re: [PATCH] hide VBox VM from desktop taskbar
You might want to run a newer Diff/patch. This one fails on latest from SVN. Maybe 4.1.6 instead of 4.1.0 Beta.??
Here is the reject file.
Oh and the user friendly part IMHO I disagree with you. I have a start/stop script that I call from a launcher. Easy and it does not require a patch to be run on every update. But that is just my opinion. Now Windows would need this for sure, so maybe someone can figure out how to do that.
Here is the reject file.
Code: Select all
--- VBoxGlobal.h 2011-07-15 16:49:08.000000000 -0400
+++ VBoxGlobal.h 2011-07-15 18:38:21.000000000 -0400
@@ -157,6 +157,7 @@
bool processArgs();
+ bool hideMachineWindow(CMachine &machine);
bool switchToMachine(CMachine &machine);
bool launchMachine(CMachine &machine);
@@ -676,6 +677,7 @@
static QString systemLanguageId();
static bool activateWindow (WId aWId, bool aSwitchDesktop = true);
+ static bool hideWindow (WId aWId);
static QString removeAccelMark (const QString &aText);
--- VBoxSelectorWnd.cpp 2011-07-15 16:49:08.000000000 -0400
+++ VBoxSelectorWnd.cpp 2011-07-15 18:25:36.000000000 -0400
@@ -154,6 +154,11 @@
QSize(32, 32), QSize(16, 16),
":/vm_start_32px.png", ":/start_16px.png",
":/vm_start_disabled_32px.png", ":/start_dis_16px.png"));
+ mVmHideAction = new QAction(this);
+ mVmHideAction->setIcon(UIIconPool::iconSetFull(
+ QSize(32, 32), QSize(16, 16),
+ ":/vm_discard_32px.png", ":/discard_16px.png",
+ ":/vm_discard_disabled_32px.png", ":/discard_dis_16px.png"));
mVmDiscardAction = new QAction(this);
mVmDiscardAction->setIcon(UIIconPool::iconSetFull(
QSize(32, 32), QSize(16, 16),
@@ -295,6 +300,7 @@
mVMMenu->addAction(mVmDeleteAction);
mVMMenu->addSeparator();
mVMMenu->addAction(mVmStartAction);
+ mVMMenu->addAction(mVmHideAction);
mVMMenu->addAction(mVmDiscardAction);
mVMMenu->addAction(mVmPauseAction);
mVMMenu->addSeparator();
@@ -314,6 +320,7 @@
mVMCtxtMenu->addAction(mVmDeleteAction);
mVMCtxtMenu->addSeparator();
mVMCtxtMenu->addAction(mVmStartAction);
+ mVMCtxtMenu->addAction(mVmHideAction);
mVMCtxtMenu->addAction(mVmDiscardAction);
mVMCtxtMenu->addAction(mVmPauseAction);
mVMCtxtMenu->addSeparator();
@@ -443,6 +450,7 @@
connect(mVmCloneAction, SIGNAL(triggered()), this, SLOT(vmClone()));
connect(mVmDeleteAction, SIGNAL(triggered()), this, SLOT(vmDelete()));
connect(mVmStartAction, SIGNAL(triggered()), this, SLOT(vmStart()));
+ connect(mVmHideAction, SIGNAL(triggered()), this, SLOT(vmHide()));
connect(mVmDiscardAction, SIGNAL(triggered()), this, SLOT(vmDiscard()));
connect(mVmPauseAction, SIGNAL(toggled(bool)), this, SLOT(vmPause(bool)));
connect(mVmRefreshAction, SIGNAL(triggered()), this, SLOT(vmRefresh()));
@@ -807,6 +815,27 @@
vboxGlobal().launchMachine(machine);
}
+void VBoxSelectorWnd::vmHide(const QString &aUuid /* = QString::null */)
+{
+ QUuid uuid(aUuid);
+ UIVMItem *item = uuid.isNull() ? mVMListView->selectedItem() :
+ mVMModel->itemById(aUuid);
+
+ AssertMsgReturnVoid(item, ("Item must be always selected here"));
+
+ /* Are we called from the mVMListView's activated() signal? */
+ if (uuid.isNull())
+ {
+ /* We always get here when mVMListView emits the activated() signal,
+ * so we must explicitly check if the action is enabled or not. */
+ if (!mVmHideAction->isEnabled())
+ return;
+ }
+
+ CMachine machine = item->machine();
+ vboxGlobal().hideMachineWindow(machine);
+}
+
void VBoxSelectorWnd::vmDiscard(const QString &aUuid /* = QString::null */)
{
UIVMItem *item = aUuid.isNull() ? mVMListView->selectedItem() :
@@ -1229,6 +1258,10 @@
/* Note: mVmStartAction text is set up in vmListViewCurrentChanged() */
+ mVmHideAction->setText(tr("&Hide"));
+ mVmHideAction->setStatusTip(
+ tr("Hide the window of the virtual machine"));
+
mVmDiscardAction->setIconText(tr("Discard"));
mVmDiscardAction->setText(tr("D&iscard Saved State"));
mVmDiscardAction->setShortcut(gSS->keySequence(UISelectorShortcuts::DiscardVMShortcut));
@@ -1362,6 +1395,7 @@
tr("Start the selected virtual machine"));
mVmStartAction->setEnabled(!running);
+ mVmHideAction->setEnabled(false);
}
else
{
@@ -1378,7 +1412,8 @@
#endif /* QT_MAC_USE_COCOA */
mVmStartAction->setStatusTip(
tr("Switch to the window of the selected virtual machine"));
-
+
+ mVmHideAction->setEnabled(item->canSwitchTo());
mVmStartAction->setEnabled(item->canSwitchTo());
}
@@ -1463,6 +1498,7 @@
mVmConfigAction->setEnabled(false);
mVmCloneAction->setEnabled(false);
mVmDeleteAction->setEnabled(item != NULL);
+ mVmHideAction->setEnabled(false);
mVmDiscardAction->setEnabled(false);
mVmPauseAction->setEnabled(false);
--- VBoxSelectorWnd.h 2011-07-15 16:49:08.000000000 -0400
+++ VBoxSelectorWnd.h 2011-07-15 18:51:08.000000000 -0400
@@ -73,6 +73,7 @@
void vmClone(const QString & = QString::null);
void vmDelete(const QString & = QString::null);
void vmStart(const QString & = QString::null);
+ void vmHide(const QString & = QString::null);
void vmDiscard(const QString & = QString::null);
void vmPause(bool, const QString & = QString::null);
void vmRefresh(const QString & = QString::null);
@@ -98,6 +99,7 @@
const QAction *vmCloneAction() const { return mVmCloneAction; }
const QAction *vmDeleteAction() const { return mVmDeleteAction; }
const QAction *vmStartAction() const { return mVmStartAction; }
+ const QAction *vmHideAction() const { return mVmHideAction; }
const QAction *vmDiscardAction() const { return mVmDiscardAction; }
const QAction *vmPauseAction() const { return mVmPauseAction; }
const QAction *vmRefreshAction() const { return mVmRefreshAction; }
@@ -169,6 +171,7 @@
QAction *mVmCloneAction;
QAction *mVmDeleteAction;
QAction *mVmStartAction;
+ QAction *mVmHideAction;
QAction *mVmDiscardAction;
QAction *mVmPauseAction;
QAction *mVmRefreshAction;
--- VBoxTrayIcon.cpp 2011-07-15 16:49:08.000000000 -0400
+++ VBoxTrayIcon.cpp 2011-07-15 18:19:39.000000000 -0400
@@ -54,6 +54,10 @@
Assert (mVmStartAction);
mVmStartAction->setIcon (mParent->vmStartAction()->icon());
+ mVmHideAction = new QAction (this);
+ Assert (mVmHideAction);
+ mVmHideAction->setIcon (mParent->vmHideAction()->icon());
+
mVmDiscardAction = new QAction (this);
Assert (mVmDiscardAction);
mVmDiscardAction->setIcon (mParent->vmDiscardAction()->icon());
@@ -116,6 +120,9 @@
mVmPauseAction->setText (mParent->vmPauseAction()->text());
mVmPauseAction->setStatusTip (mParent->vmPauseAction()->statusTip());
+ mVmHideAction->setText (mParent->vmHideAction()->text());
+ mVmHideAction->setStatusTip (mParent->vmHideAction()->statusTip());
+
mVmDiscardAction->setText (mParent->vmDiscardAction()->text());
mVmDiscardAction->setStatusTip (mParent->vmDiscardAction()->statusTip());
@@ -141,6 +148,7 @@
mVmConfigAction->setData (vID);
mVmDeleteAction->setData (vID);
+ mVmHideAction->setData (vID);
mVmDiscardAction->setData (vID);
mVmStartAction->setData (vID);
mVmPauseAction->setData (vID);
@@ -217,6 +225,7 @@
/* Disconnect old slot which maybe was connected from another selected sub menu. */
disconnect (mVmConfigAction, SIGNAL (triggered()), this, SLOT (vmSettings()));
disconnect (mVmDeleteAction, SIGNAL (triggered()), this, SLOT (vmDelete()));
+ disconnect (mVmHideAction, SIGNAL (triggered()), this, SLOT (vmHide()));
disconnect (mVmDiscardAction, SIGNAL (triggered()), this, SLOT (vmDiscard()));
disconnect (mVmStartAction, SIGNAL (triggered()), this, SLOT (vmStart()));
disconnect (mVmPauseAction, SIGNAL (toggled (bool)), this, SLOT (vmPause (bool)));
@@ -225,6 +234,7 @@
/* Connect new sub menu with slots. */
connect (mVmConfigAction, SIGNAL (triggered()), this, SLOT (vmSettings()));
connect (mVmDeleteAction, SIGNAL (triggered()), this, SLOT (vmDelete()));
+ connect (mVmHideAction, SIGNAL (triggered()), this, SLOT (vmHide()));
connect (mVmDiscardAction, SIGNAL (triggered()), this, SLOT (vmDiscard()));
connect (mVmStartAction, SIGNAL (triggered()), this, SLOT (vmStart()));
connect (mVmPauseAction, SIGNAL (toggled (bool)), this, SLOT (vmPause (bool)));
--- VBoxTrayIcon.h 2011-07-15 16:49:08.000000000 -0400
+++ VBoxTrayIcon.h 2011-07-15 18:15:59.000000000 -0400
@@ -81,6 +81,7 @@
QAction *mVmConfigAction;
QAction *mVmDeleteAction;
QAction *mVmStartAction;
+ QAction *mVmHideAction;
QAction *mVmDiscardAction;
QAction *mVmPauseAction;
QAction *mVmRefreshAction;
-
- Volunteer
- Posts: 1003
- Joined: 5. Sep 2008, 14:40
- Primary OS: Debian other
- VBox Version: PUEL
- Guest OSses: Solaris, Linux, Windows, OS/2, MacOSX, FreeBSD
- Contact:
Re: [PATCH] hide VBox VM from desktop taskbar
one function i've always though virtualbox lacks (and vmware had, dunno if it still does) is the ability to close the window and still keep the vm running. i just picked up on the attach/detach in your quote there.
i mean the actual vm window, not the vbox manager window. essentially switching from gui to headless mode, then you go back to the manager window to switch it back to gui mode if you want.
i would also find that handy for when you want a console window open to see boot messages and don't want to setup a serial pipe, but then once booted you only want to ssh in. as far as i know vboxheadless doesn't provide console messages. that's something that openvz (and i think kvm/xen) does nicely.
but back to your issue - in gnome3 there isn't a desktop taskbar as such, for instance i now have 3 vm's and the manager window open and only see one icon for the active window.
i mean the actual vm window, not the vbox manager window. essentially switching from gui to headless mode, then you go back to the manager window to switch it back to gui mode if you want.
i would also find that handy for when you want a console window open to see boot messages and don't want to setup a serial pipe, but then once booted you only want to ssh in. as far as i know vboxheadless doesn't provide console messages. that's something that openvz (and i think kvm/xen) does nicely.
but back to your issue - in gnome3 there isn't a desktop taskbar as such, for instance i now have 3 vm's and the manager window open and only see one icon for the active window.
-
- Volunteer
- Posts: 3342
- Joined: 10. May 2007, 16:59
- Location: Israel
Re: [PATCH] hide VBox VM from desktop taskbar
Sej: my patch does address your issue.
It hides VM *completely* from desktop. To show it again, you need to use VBox Manager GUI, and double-click on VM.
It hides VM *completely* from desktop. To show it again, you need to use VBox Manager GUI, and double-click on VM.