Skip to content

Commit

Permalink
Adds moveWindow impl.
Browse files Browse the repository at this point in the history
  • Loading branch information
mntone committed Dec 30, 2022
1 parent ebdbfda commit 6916069
Show file tree
Hide file tree
Showing 13 changed files with 314 additions and 14 deletions.
25 changes: 25 additions & 0 deletions src/PositiveDesktop/Common/VirtualDesktop.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,31 @@ namespace app {
AD_RIGHT = 4,
};

// Supported OS:
// - [17763] October 2018 Update (1809) / Redstone 5
// - [18362] May 2019 Update (1903) / 19H1
// - [18363] November 2019 Update (1909) / 19H2
// - [19041] May 2020 Update (2004) / 20H1
// - [19042] October 2020 Update (20H2) / 20H2
// - [19043] May 2021 Update (21H1) / 21H1
// - [19044] November 2021 Update (21H2) / 21H2
// - [19045] 2022 Update (22H2) / 22H2
// - [22000] Windows 11 Version 21H2
// - [22621] Windows 11 Version 22H2
struct __declspec(uuid("1841C6D7-4F9D-42C0-AF41-8747538F10E5")) IApplicationViewCollection: public IUnknown {
virtual HRESULT __stdcall GetViews(IObjectArray** ppViews) = 0;
virtual HRESULT __stdcall GetViewsByZOrder(IObjectArray** ppViews) = 0;
virtual HRESULT __stdcall GetViewsByAppUserModelId(LPCWSTR id, IObjectArray** ppViews) = 0;
virtual HRESULT __stdcall GetViewForHwnd(HWND hWnd, /*IApplicationView*/ IUnknown** ppView) = 0;
virtual HRESULT __stdcall GetViewForApplication(/*IImmersiveApplication*/ IUnknown* pImmersiveApplication, /*IApplicationView*/ IUnknown** ppView) = 0;
virtual HRESULT __stdcall GetViewForAppUserModelId(LPCWSTR id, /*IApplicationView*/ IUnknown** ppView) = 0;
virtual HRESULT __stdcall GetViewInFocus(/*IApplicationView*/ IUnknown** ppView) = 0;
virtual HRESULT __stdcall Unknown1(/*IApplicationView*/ IUnknown** ppView) = 0;
virtual HRESULT __stdcall RefreshCollection() = 0;
virtual HRESULT __stdcall RegisterForApplicationViewChanges(/*IApplicationViewChangeListener*/ IUnknown* pListener, DWORD* dwCookie) = 0;
virtual HRESULT __stdcall UnregisterForApplicationViewChanges(DWORD dwCookie) = 0;
};

}

namespace app::win10 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ void VirtualDesktopNotificationService::initialize(uint32_t build) {
}
}

void VirtualDesktopNotificationService::moveWindowLeft() noexcept try {
impl_->moveForegroundWindowToLeftOfCurrent();
} catch (winrt::hresult_error const& /*err*/) {
// TODO: error log
}

void VirtualDesktopNotificationService::moveWindowRight() noexcept try {
impl_->moveForegroundWindowToRightOfCurrent();
} catch (winrt::hresult_error const& /*err*/) {
// TODO: error log
}

#include "vdevent_t.h"

void FASTCALL VirtualDesktopNotificationService::on(reps::bag_t const& value) noexcept {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ namespace app::listener {

void initialize(uint32_t build);

// - Desktop actions
void moveWindowLeft() noexcept;
void moveWindowRight() noexcept;

private:
void FASTCALL on(reps::bag_t const& value) noexcept override;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace app {
struct IVirtualDesktopNotificationServiceImpl {
virtual ~IVirtualDesktopNotificationServiceImpl() { }

virtual void moveForegroundWindowToLeftOfCurrent() const = 0;
virtual void moveForegroundWindowToRightOfCurrent() const = 0;
virtual void close() = 0;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ VirtualDesktopNotificationServiceWin10::VirtualDesktopNotificationServiceWin10(r
guid_of<IServiceProvider>(),
serviceProvider_.put_void()));

check_hresult(serviceProvider_->QueryService(
__uuidof(IApplicationViewCollection),
__uuidof(IApplicationViewCollection),
applicationViewCollection_.put_void()));

check_hresult(serviceProvider_->QueryService(
clsidVirtualDesktopManagerInternal,
__uuidof(IVirtualDesktopManagerInternal2),
Expand Down Expand Up @@ -103,6 +108,34 @@ void VirtualDesktopNotificationServiceWin10::close() {

#pragma endregion

#pragma region Operation implementation

void VirtualDesktopNotificationServiceWin10::moveForegroundWindowToLeftOfCurrent() const {
com_ptr<IVirtualDesktop> current;
check_hresult(virtualDesktopManager_->GetCurrentDesktop(current.put()));

com_ptr<IVirtualDesktop> left;
check_hresult(virtualDesktopManager_->GetAdjacentDesktop(current.get(), AD_LEFT, left.put()));

com_ptr<IUnknown> view;
check_hresult(applicationViewCollection_->GetViewForHwnd(GetForegroundWindow(), view.put()));
check_hresult(virtualDesktopManager_->MoveViewToDesktop(view.get(), left.get()));
}

void VirtualDesktopNotificationServiceWin10::moveForegroundWindowToRightOfCurrent() const {
com_ptr<IVirtualDesktop> current;
check_hresult(virtualDesktopManager_->GetCurrentDesktop(current.put()));

com_ptr<IVirtualDesktop> right;
check_hresult(virtualDesktopManager_->GetAdjacentDesktop(current.get(), AD_RIGHT, right.put()));

com_ptr<IUnknown> view;
check_hresult(applicationViewCollection_->GetViewForHwnd(GetForegroundWindow(), view.put()));
check_hresult(virtualDesktopManager_->MoveViewToDesktop(view.get(), right.get()));
}

#pragma endregion

#pragma region Sink implementation

#include "vdevent_t.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ namespace app::win10 {

void close() override;

// - Operations
void moveForegroundWindowToLeftOfCurrent() const override;
void moveForegroundWindowToRightOfCurrent() const override;

// - IVirtualDesktopNotification
IFACEMETHOD(VirtualDesktopCreated)(IVirtualDesktop* pDesktop);
IFACEMETHOD(VirtualDesktopDestroyBegin)(IVirtualDesktop* pDesktopDestroyed, IVirtualDesktop* pDesktopFallback);
Expand All @@ -29,6 +33,7 @@ namespace app::win10 {

private:
winrt::com_ptr<IServiceProvider> serviceProvider_;
winrt::com_ptr<IApplicationViewCollection> applicationViewCollection_;
winrt::com_ptr<IVirtualDesktopManagerInternal2> virtualDesktopManager_;
winrt::com_ptr<IVirtualDesktopNotificationService> virtualDesktopNotificationService_;
DWORD cookie_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,22 @@ struct VirtualDesktopManagerInternalDelegate21313 final: public IVirtualDesktopM
virtualDesktopManager_.put_void()));
}

HRESULT GetDesktops(IObjectArray** ppArray) noexcept {
inline HRESULT MoveViewToDesktop(IUnknown* pView, IVirtualDesktop* pDesktop) noexcept override {
return virtualDesktopManager_->MoveViewToDesktop(pView, pDesktop);
}

inline HRESULT GetCurrentDesktop(IVirtualDesktop** ppDesktop) noexcept override {
return virtualDesktopManager_->GetCurrentDesktop(nullptr, ppDesktop);
}

inline HRESULT GetDesktops(IObjectArray** ppArray) noexcept override {
return virtualDesktopManager_->GetDesktops(nullptr, ppArray);
}

inline HRESULT GetAdjacentDesktop(IVirtualDesktop* pDesktopOrigin, app::AdjacentDesktopDirection nDirection, IVirtualDesktop** ppDesktop) noexcept override {
return virtualDesktopManager_->GetAdjacentDesktop(pDesktopOrigin, nDirection, ppDesktop);
}

private:
winrt::com_ptr<IVirtualDesktopManagerInternal21313> virtualDesktopManager_;
};
Expand All @@ -35,10 +47,22 @@ struct VirtualDesktopManagerInternalDelegate21359 final: public IVirtualDesktopM
virtualDesktopManager_.put_void()));
}

HRESULT GetDesktops(IObjectArray** ppArray) noexcept {
inline HRESULT MoveViewToDesktop(IUnknown* pView, IVirtualDesktop* pDesktop) noexcept override {
return virtualDesktopManager_->MoveViewToDesktop(pView, pDesktop);
}

inline HRESULT GetCurrentDesktop(IVirtualDesktop** ppDesktop) noexcept override {
return virtualDesktopManager_->GetCurrentDesktop(nullptr, ppDesktop);
}

inline HRESULT GetDesktops(IObjectArray** ppArray) noexcept override {
return virtualDesktopManager_->GetDesktops(nullptr, ppArray);
}

inline HRESULT GetAdjacentDesktop(IVirtualDesktop* pDesktopOrigin, app::AdjacentDesktopDirection nDirection, IVirtualDesktop** ppDesktop) noexcept override {
return virtualDesktopManager_->GetAdjacentDesktop(pDesktopOrigin, nDirection, ppDesktop);
}

private:
winrt::com_ptr<IVirtualDesktopManagerInternal21359> virtualDesktopManager_;
};
Expand All @@ -51,10 +75,22 @@ struct VirtualDesktopManagerInternalDelegate22449 final: public IVirtualDesktopM
virtualDesktopManager_.put_void()));
}

HRESULT GetDesktops(IObjectArray** ppArray) noexcept {
inline HRESULT MoveViewToDesktop(IUnknown* pView, IVirtualDesktop* pDesktop) noexcept override {
return virtualDesktopManager_->MoveViewToDesktop(pView, pDesktop);
}

inline HRESULT GetCurrentDesktop(IVirtualDesktop** ppDesktop) noexcept override {
return virtualDesktopManager_->GetCurrentDesktop(nullptr, ppDesktop);
}

inline HRESULT GetDesktops(IObjectArray** ppArray) noexcept override {
return virtualDesktopManager_->GetDesktops(nullptr, ppArray);
}

inline HRESULT GetAdjacentDesktop(IVirtualDesktop* pDesktopOrigin, app::AdjacentDesktopDirection nDirection, IVirtualDesktop** ppDesktop) noexcept override {
return virtualDesktopManager_->GetAdjacentDesktop(pDesktopOrigin, nDirection, ppDesktop);
}

private:
winrt::com_ptr<IVirtualDesktopManagerInternal22449> virtualDesktopManager_;
};
Expand All @@ -67,10 +103,22 @@ struct VirtualDesktopManagerInternalDelegate25158 final: public IVirtualDesktopM
virtualDesktopManager_.put_void()));
}

HRESULT GetDesktops(IObjectArray** ppArray) noexcept {
inline HRESULT MoveViewToDesktop(IUnknown* pView, IVirtualDesktop* pDesktop) noexcept override {
return virtualDesktopManager_->MoveViewToDesktop(pView, pDesktop);
}

inline HRESULT GetCurrentDesktop(IVirtualDesktop** ppDesktop) noexcept override {
return virtualDesktopManager_->GetCurrentDesktop(nullptr, ppDesktop);
}

inline HRESULT GetDesktops(IObjectArray** ppArray) noexcept override {
return virtualDesktopManager_->GetDesktops(nullptr, ppArray);
}

inline HRESULT GetAdjacentDesktop(IVirtualDesktop* pDesktopOrigin, app::AdjacentDesktopDirection nDirection, IVirtualDesktop** ppDesktop) noexcept override {
return virtualDesktopManager_->GetAdjacentDesktop(pDesktopOrigin, nDirection, ppDesktop);
}

private:
winrt::com_ptr<IVirtualDesktopManagerInternal25158> virtualDesktopManager_;
};
Expand Down Expand Up @@ -126,6 +174,11 @@ VirtualDesktopNotificationServiceWin11::VirtualDesktopNotificationServiceWin11(D
guid_of<IServiceProvider>(),
serviceProvider_.put_void()));

check_hresult(serviceProvider_->QueryService(
__uuidof(IApplicationViewCollection),
__uuidof(IApplicationViewCollection),
applicationViewCollection_.put_void()));

if (build >= 25158) {
virtualDesktopManagerDelegate_ = std::make_unique<VirtualDesktopManagerInternalDelegate25158>(serviceProvider_.get());
} else if (build >= 22449) {
Expand Down Expand Up @@ -178,6 +231,34 @@ void VirtualDesktopNotificationServiceWin11::close() {

#pragma endregion

#pragma region Operation implementation

void VirtualDesktopNotificationServiceWin11::moveForegroundWindowToLeftOfCurrent() const {
com_ptr<IVirtualDesktop> current;
check_hresult(virtualDesktopManagerDelegate_->GetCurrentDesktop(current.put()));

com_ptr<IVirtualDesktop> left;
check_hresult(virtualDesktopManagerDelegate_->GetAdjacentDesktop(current.get(), AD_LEFT, left.put()));

com_ptr<IUnknown> view;
check_hresult(applicationViewCollection_->GetViewInFocus(view.put()));
check_hresult(virtualDesktopManagerDelegate_->MoveViewToDesktop(view.get(), left.get()));
}

void VirtualDesktopNotificationServiceWin11::moveForegroundWindowToRightOfCurrent() const {
com_ptr<IVirtualDesktop> current;
check_hresult(virtualDesktopManagerDelegate_->GetCurrentDesktop(current.put()));

com_ptr<IVirtualDesktop> right;
check_hresult(virtualDesktopManagerDelegate_->GetAdjacentDesktop(current.get(), AD_RIGHT, right.put()));

com_ptr<IUnknown> view;
check_hresult(applicationViewCollection_->GetViewInFocus(view.put()));
check_hresult(virtualDesktopManagerDelegate_->MoveViewToDesktop(view.get(), right.get()));
}

#pragma endregion

#pragma region Sink implementation

#include "vdevent_t.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ namespace app::win11 {
struct IVirtualDesktopManagerInternalDelegate {
virtual ~IVirtualDesktopManagerInternalDelegate() { }

virtual HRESULT MoveViewToDesktop(IUnknown* pView, IVirtualDesktop* pDesktop) noexcept = 0;
virtual HRESULT GetCurrentDesktop(IVirtualDesktop** ppDesktop) noexcept = 0;
virtual HRESULT GetDesktops(IObjectArray** ppArray) noexcept = 0;
virtual HRESULT GetAdjacentDesktop(IVirtualDesktop* pDesktopOrigin, AdjacentDesktopDirection nDirection, IVirtualDesktop** ppDesktop) noexcept = 0;
};

struct VirtualDesktopNotificationServiceWin11
Expand All @@ -19,6 +22,10 @@ namespace app::win11 {

void close() override;

// - Operations
void moveForegroundWindowToLeftOfCurrent() const override;
void moveForegroundWindowToRightOfCurrent() const override;

// - IVirtualDesktopNotification
IFACEMETHOD(VirtualDesktopCreated)(IVirtualDesktop* pDesktop);
IFACEMETHOD(VirtualDesktopDestroyBegin)(IVirtualDesktop* pDesktopDestroyed, IVirtualDesktop* pDesktopFallback);
Expand All @@ -36,6 +43,7 @@ namespace app::win11 {

private:
winrt::com_ptr<IServiceProvider> serviceProvider_;
winrt::com_ptr<IApplicationViewCollection> applicationViewCollection_;
std::unique_ptr<IVirtualDesktopManagerInternalDelegate> virtualDesktopManagerDelegate_;
winrt::com_ptr<IVirtualDesktopNotificationService> virtualDesktopNotificationService_;
DWORD cookie_;
Expand Down
22 changes: 18 additions & 4 deletions src/PositiveDesktop/Services/app_t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,24 @@ void FASTCALL app_t::on(reps::bag_t const& value) noexcept {
void app_t::process(keylistener::kbevent_t ev) noexcept {
using namespace app::keylistener;

switch (ev) {
case kbe_exit:
message_service_t::terminateWithoutLock();
presenter_->closeAll();
switch (flag(ev)) {
case kbe_extend:
switch (ev) {
case kbe_exit:
message_service_t::terminateWithoutLock();
presenter_->closeAll();
break;
}
break;
case kbe_move_window:
switch (ev) {
case kbe_move_window_left:
notificationListener_->moveWindowLeft();
break;
case kbe_move_window_right:
notificationListener_->moveWindowRight();
break;
}
break;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,20 @@ LRESULT KeysListenerService::KbdProc(HHOOK hHook, int nCode, WPARAM wParam, KBDL
reps::next(subject_, kbe_exit);
return TRUE;
}

// Win+Ctrl+Alt+←: Move window to the left desktop.
if (VK_LEFT == kbdStruct.vkCode && IsKeyPressed(VK_LCONTROL) && IsKeyPressed(VK_LWIN) && IsKeyPressed(VK_LMENU)) {
handled = true;
reps::next(subject_, kbe_move_window_left);
return TRUE;
}

// Win+Ctrl+Alt+→: Move window to the right desktop.
if (VK_RIGHT == kbdStruct.vkCode && IsKeyPressed(VK_LCONTROL) && IsKeyPressed(VK_LWIN) && IsKeyPressed(VK_LMENU)) {
handled = true;
reps::next(subject_, kbe_move_window_right);
return TRUE;
}
return FALSE;
}

Expand Down
Loading

0 comments on commit 6916069

Please sign in to comment.