#include "WorkspacesMenu.h"
#include "..\API\BBApi.h"
#include "..\Menu\MenuCommon.h"
#include "..\Menu\MenuItem.h"
#include "..\Settings\Settings.h"
#include "..\Workspaces\Workspaces.h"
#include <dwmapi.h>
extern MenuCommon *pMenuCommon;
extern Settings *pSettings;
extern Workspaces *pWorkspaces;
#define WORKSPACES_FOLDER_TIMER 4434
WorkspacesMenu::WorkspacesMenu(const char *pszTitle) : Menu(pMenuCommon->hInst)
{
m_pszTitle = pszTitle ? _strdup(pszTitle) : _strdup("");
}
WorkspacesMenu::~WorkspacesMenu()
{
if (m_pszTitle) free(m_pszTitle);
m_pszTitle = NULL;
}
void WorkspacesMenu::OnShow(bool fShow)
{
if (fShow) UpdateFolder();
}
bool WorkspacesMenu::OnUser(int nMessage, WPARAM wParam, LPARAM lParam, LRESULT &lResult)
{
if (nMessage == BB_DESKTOPINFO)
{
DesktopInfo *pDesktopInfo = (DesktopInfo*)lParam;
char desktopNameANSI[MAX_LINE_LENGTH];
strcpy_s(desktopNameANSI, sizeofArray(desktopNameANSI), pDesktopInfo->name);
strcat_s(desktopNameANSI, sizeofArray(desktopNameANSI), "\0");
wchar_t desktopNameUnicode[MAX_LINE_LENGTH];
MultiByteToWideChar(CP_UTF8, 0, desktopNameANSI, strnlen_s(desktopNameANSI, sizeofArray(desktopNameANSI))+1, desktopNameUnicode, MAX_LINE_LENGTH);
WorkspacesMenuItem *item = new WorkspacesMenuItem(desktopNameANSI, desktopNameUnicode, pDesktopInfo->number);
item->SetHeight(pMenuCommon->m_nSubmenuHeight);
AddMenuItem(item);
return true;
}
return Menu::OnUser(nMessage, wParam, lParam, lResult);
}
void WorkspacesMenu::UpdateFolder()
{
DeleteMenuItems();
pMenuCommon->AddHeaderItem(this, m_pszTitle);
WorkspacesMenuItem *item = new WorkspacesMenuItem("Minimized windows", L"Minimized windows", 255);
item->SetHeight(pMenuCommon->m_nSubmenuHeight);
AddMenuItem(item);
pMenuCommon->CreateMenuItem(this, MENUITEM_SEPARATOR, NULL, NULL, NULL, false);
SendMessage(GetBBWnd(), BB_LISTDESKTOPS, (WPARAM)GetWindow(), 0);
pMenuCommon->CreateMenuItem(this, MENUITEM_SEPARATOR, NULL, NULL, NULL, false);
pMenuCommon->CreateMenuItem(this, MENUITEM_COMMAND, "@xoblite RestoreAll", NULL, "Restore all windows...", false);
pMenuCommon->CreateMenuItem(this, MENUITEM_COMMAND, "@xoblite MinimizeAll", NULL, "Minimize all windows...", false);
pMenuCommon->CreateMenuItem(this, MENUITEM_SEPARATOR, NULL, NULL, NULL, false);
pMenuCommon->CreateMenuItem(this, MENUITEM_COMMAND, "@xoblite Workspaces", "GatherWindows", "Gather all windows...", false);
pMenuCommon->CreateMenuItem(this, MENUITEM_SEPARATOR, NULL, NULL, NULL, false);
pMenuCommon->CreateMenuItem(this, MENUITEM_COMMAND, "@xoblite Workspaces", "New", "New workspace", false);
pMenuCommon->CreateMenuItem(this, MENUITEM_COMMAND, "@xoblite Workspaces", "Remove", "Remove last workspace", false);
pMenuCommon->CreateMenuItem(this, MENUITEM_SEPARATOR, NULL, NULL, NULL, false);
pMenuCommon->CreateMenuItem(this, MENUITEM_BOOLEAN, "@xoblite Workspaces", "ToggleMousewheelChanging", "Mousewheel changing", pSettings->mousewheelChanging);
pMenuCommon->CreateMenuItem(this, MENUITEM_BOOLEAN, "@xoblite Workspaces", "ToggleFollowActive", "Follow active task", pSettings->followActive);
pMenuCommon->CreateMenuItem(this, MENUITEM_BOOLEAN, "@xoblite Workspaces", "ToggleWallpaperPerWorkspace", "Wallpaper per workspace", pSettings->wallpaperPerWorkspace);
pMenuCommon->AddFooterItem(this, "");
Invalidate();
Validate();
}
WorkspacesMenuItem::WorkspacesMenuItem(char* pszTitleANSI, wchar_t* pszTitleUnicode, int nDesktop) : FolderItem(NULL, pszTitleANSI, pszTitleUnicode)
{
m_nDesktop = nDesktop;
m_nTimer = 0;
}
WorkspacesMenuItem::~WorkspacesMenuItem()
{
m_pParent->RemoveChild(m_pSubMenu);
if (m_pSubMenu) delete m_pSubMenu;
m_pSubMenu = NULL;
}
void WorkspacesMenuItem::Invoke()
{
m_pParent->Hide(HIDE_CHILDREN);
m_pParent->Hide(HIDE_PARENTS);
pWorkspaces->SwitchToWorkspace(m_nDesktop);
}
bool WorkspacesMenuItem::Active(bool bActivate)
{
if (bActivate && !m_bActive) UpdateFolder();
return FolderItem::Active(bActivate);
}
void WorkspacesMenuItem::UpdateFolder()
{
m_pSubMenu->DeleteMenuItems();
pMenuCommon->AddHeaderItem(m_pSubMenu, m_pszTitleANSI);
numberOfTasksOnThisWorkspace = 0;
EnumWindows(CheckTaskEnumProc, (LPARAM)this);
if (numberOfTasksOnThisWorkspace == 0) pMenuCommon->CreateMenuItem(m_pSubMenu, MENUITEM_NOP, NULL, NULL, "(No tasks on this workspace)", false);
pMenuCommon->AddFooterItem(m_pSubMenu, "");
m_pSubMenu->Sort(2,2);
m_pSubMenu->Invalidate();
m_pSubMenu->Validate();
}
void WorkspacesMenuItem::AddWindow(HWND hWnd)
{
char pszWindowText[1024], wndstring[10];
wchar_t pszWindowTextUnicode[1024];
GetWindowText(hWnd, pszWindowText, sizeof(pszWindowText));
GetWindowTextW(hWnd, pszWindowTextUnicode, sizeof(pszWindowTextUnicode));
_ultoa((unsigned long)hWnd, wndstring, 16);
pMenuCommon->CreateMenuItemUnicode(m_pSubMenu, MENUITEM_COMMAND, "<task_item>", wndstring, pszWindowTextUnicode, false);
numberOfTasksOnThisWorkspace++;
}
void WorkspacesMenuItem::Attached(Menu* pMenu)
{
m_pParent = pMenu;
m_pSubMenu = new Menu(pMenuCommon->hInst);
m_pParent->AddChild(m_pSubMenu);
m_pSubMenu->SetParent(m_pParent);
SetTimer(GetWindow(), WORKSPACES_FOLDER_TIMER, 2000, NULL);
}
void WorkspacesMenuItem::Timer(int nTimer)
{
FolderItem::Timer(nTimer);
if (nTimer == WORKSPACES_FOLDER_TIMER && IsWindowVisible(m_pSubMenu->GetWindow()))
{
UpdateFolder();
}
}
BOOL CALLBACK CheckTaskEnumProc(HWND hwnd, LPARAM lParam)
{
if (!IsAppWindow(hwnd)) return true;
int cloaked = 0;
HRESULT hr = DwmGetWindowAttribute(hwnd, DWMWA_CLOAKED, &cloaked, 4);
if ((hr == S_OK) && (cloaked > 0)) return true;
WorkspacesMenuItem* wmi = (WorkspacesMenuItem*)lParam;
if (wmi->m_nDesktop == 255)
{
if (IsIconic(hwnd)) wmi->AddWindow(hwnd);
}
else if (wmi->m_nDesktop == 254)
{
wmi->AddWindow(hwnd);
}
else
{
if (!IsIconic(hwnd) && (pWorkspaces->GetWorkspaceByWindow(hwnd) == wmi->m_nDesktop)) wmi->AddWindow(hwnd);
}
return true;
}