Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User/lamotile/add powerlauncher project #1287

Merged
5 commits merged into from
Feb 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions PowerToys.sln
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowWalker", "src\modules
{74485049-C722-400F-ABE5-86AC52D929B3} = {74485049-C722-400F-ABE5-86AC52D929B3}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "powerlauncher", "powerlauncher", "{E7DA6A44-A1FC-4850-8902-47F59FB7F32C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerLauncher", "src\modules\powerlauncher\PowerLauncher\PowerLauncher.vcxproj", "{947BBD90-69B0-47AB-9A77-93D85672E1DE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerLauncherTest", "src\modules\powerlauncher\PowerLauncherTest\PowerLauncherTest.vcxproj", "{1A2062AF-DAB7-439E-8CFF-C9C49D86990B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Expand Down Expand Up @@ -212,6 +218,14 @@ Global
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Debug|x64.Build.0 = Debug|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Release|x64.ActiveCfg = Release|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Release|x64.Build.0 = Release|x64
{947BBD90-69B0-47AB-9A77-93D85672E1DE}.Debug|x64.ActiveCfg = Debug|x64
{947BBD90-69B0-47AB-9A77-93D85672E1DE}.Debug|x64.Build.0 = Debug|x64
{947BBD90-69B0-47AB-9A77-93D85672E1DE}.Release|x64.ActiveCfg = Release|x64
{947BBD90-69B0-47AB-9A77-93D85672E1DE}.Release|x64.Build.0 = Release|x64
{1A2062AF-DAB7-439E-8CFF-C9C49D86990B}.Debug|x64.ActiveCfg = Debug|x64
{1A2062AF-DAB7-439E-8CFF-C9C49D86990B}.Debug|x64.Build.0 = Debug|x64
{1A2062AF-DAB7-439E-8CFF-C9C49D86990B}.Release|x64.ActiveCfg = Release|x64
{1A2062AF-DAB7-439E-8CFF-C9C49D86990B}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -240,6 +254,9 @@ Global
{8DC78AF7-DC3E-4C57-A8FB-7E347DE74A03} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB} = {8DC78AF7-DC3E-4C57-A8FB-7E347DE74A03}
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6} = {8DC78AF7-DC3E-4C57-A8FB-7E347DE74A03}
{E7DA6A44-A1FC-4850-8902-47F59FB7F32C} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{947BBD90-69B0-47AB-9A77-93D85672E1DE} = {E7DA6A44-A1FC-4850-8902-47F59FB7F32C}
{1A2062AF-DAB7-439E-8CFF-C9C49D86990B} = {E7DA6A44-A1FC-4850-8902-47F59FB7F32C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
Expand Down
17 changes: 17 additions & 0 deletions doc/specs/FancyZones-DCR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
### FancyZones library brief overview
---

1. `Zone` - Class which is basically wrapper around rectangle structure, representing one zone inside applied zone layout. ZoneSet is holding array of these which represent zone layout.
2. `ZoneSet` - Class implementing actual zone layout applied. What this means is that ZoneSet is responsible for actual calculation of rectangle coordinates (whether is grid or canvas layout) and moving window through them. ZoneWindow holds ZoneSet structure which represents currently active zone set.
3. `ZoneWindow` - Class representing work area, which is defined by monitor and current virtual desktop. For an example, if You have two monitors connected and two virtual desktops, You have 4 work areas available, and each of them can have separate zone layout. ZoneWindow is describing single work area. As mentioned before it holds active ZoneSet.
4. `FancyZones` - Top level entity and entry point for all user actions (which goes through actual module interface). Some of the main responsibilities of FancyZones class:
1. Starting FancyZones Editor (C#) with appropriate command line arguments on user request.
2. Keeping track of ZoneWindow per monitor (currently active work area on each connected monitor).
3. Keeping track of active virtual desktops. This is performed in separate thread by polling VirtualDesktopIDs registry key and parsing its content.
4. Detecting every change in work environment, such as creating / destroying / switching between virtual desktops, closing FancyZones Editor, changing display settings and handling those changes.

### Proposal for modifications of handling described in 4.4:

Currently after each of the mentioned changes in work environment we are calling EnumDisplayMonitors windows API, and passing callback function to it. EnumDisplayMonitors works asynchronous and triggers that callback for each work area available (as mentioned in previous example, for two monitors and two virtual desktops, we have this callback triggered four times). As mentioned previously, we have ZoneWindow class as our representation of this work area. And what we do, every time this callback is triggered we destroy previous ZoneWindow object for that work area and create new one, even though that it is most likely that nothing has changed (e.g. just switching back and forth between virtual desktops). This constant creating and deleting of ZoneWindow was root cause for several bugs in the past and it is reason that we have several hacky solutions in that part of code. Because of that it is really important for us to optimize it.

As mentioned in 4.3 we already have tracker of virtual desktops implemented. Idea is to use this functionality and to extend it bit more, so we can track if work area (ZoneWindow) is new one, or already processed and skip creating new ZoneWindow objects and deleting old ones every time, even if nothing changed in it. We will keep map, where virtual desktop id is the key, and values are already processed monitors (virtual desktop exists across all monitors). Once we receive callback from EnumDisplayMonitors, indicating work area (defined by virtual desktop id and monitor) we can check if it’s new or not, and act accordingly (create new ZoneWindow for it or not). Deleting virtual desktop (which is also registered in 4.3), will trigger updates in this map, and also updates in our JSON storage.
2 changes: 1 addition & 1 deletion src/common/notifications_winrt/notifications.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.17134.0</WindowsTargetPlatformMinVersion>
<WindowsTargetPlatformMinVersion>10.0.18362.0</WindowsTargetPlatformMinVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<ItemGroup Label="ProjectConfigurations">
Expand Down
90 changes: 90 additions & 0 deletions src/modules/powerlauncher/PowerLauncher/PowerLauncher.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include "pch.h"
#include <settings_objects.h>
#include <common.h>
#include "PowerLauncher.h"

// Destroy the powertoy and free memory.
void PowerLauncherModule::destroy()
{
Trace::Destroy();
delete this;
}

// Return the display name of the powertoy, this will be cached.
const wchar_t* PowerLauncherModule::get_name()
{
return m_moduleName.c_str();
}

const wchar_t** PowerLauncherModule::get_events()
{
return nullptr;
}

// Return JSON with the configuration options.
bool PowerLauncherModule::get_config(_Out_ wchar_t* buffer, _Out_ int* buffer_size)
{
HINSTANCE hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);

// Create a Settings object.
PowerToysSettings::Settings settings(hinstance, get_name());

// General Settings.
settings.set_description(GET_RESOURCE_STRING(IDS_GENERAL_DESCRIPTION));
return settings.serialize_to_buffer(buffer, buffer_size);
}

// Called by the runner to pass the updated settings values as a serialized JSON.
void PowerLauncherModule::set_config(const wchar_t* config)
{
try
{
PowerToysSettings::PowerToyValues values = PowerToysSettings::PowerToyValues::from_json_string(config);
values.save_to_settings_file();
}
catch (std::exception const& e)
{
Trace::SetConfigInvalidJSON(e.what());
}
}

// Enable the powertoy
void PowerLauncherModule::enable()
{
Trace::PowerToyIsEnabled();
this->m_enabled = true;
}

// Disable the powertoy
void PowerLauncherModule::disable()
{
Trace::PowerToyIsDisabled();
this->m_enabled = false;
}

// Returns if the powertoys is enabled
bool PowerLauncherModule::is_enabled()
{
return this->m_enabled;
}

// Handle incoming event, data is event-specific
intptr_t PowerLauncherModule::signal_event(const wchar_t* name, intptr_t data)
{
return 0;
}

// Load the settings file.
void PowerLauncherModule::init_settings()
{
try
{
// Load and parse the settings file for this PowerToy.
PowerToysSettings::PowerToyValues settings =
PowerToysSettings::PowerToyValues::load_from_settings_file(PowerLauncherModule::get_name());
}
catch (std::exception const& e)
{
Trace::InitSetErrorLoadingFile(e.what());
}
}
35 changes: 35 additions & 0 deletions src/modules/powerlauncher/PowerLauncher/PowerLauncher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "pch.h"
#include <interface/powertoy_module_interface.h>
#include <common.h>

extern "C" IMAGE_DOS_HEADER __ImageBase;

// Implement the PowerToy Module Interface and all the required methods.
class PowerLauncherModule : public PowertoyModuleIface
{
private:
// The PowerToy state.
bool m_enabled = false;
std::wstring m_moduleName;

public:
PowerLauncherModule()
:
m_moduleName(GET_RESOURCE_STRING(IDS_MODULE_NAME))
{
init_settings();
};

virtual void destroy();
virtual const wchar_t* get_name();
virtual const wchar_t** get_events();
virtual bool get_config(_Out_ wchar_t* buffer, _Out_ int* buffer_size);
virtual void set_config(const wchar_t* config);
virtual void enable();
virtual void disable();
virtual bool is_enabled();
virtual void init_settings();
virtual intptr_t signal_event(const wchar_t* name, intptr_t data);
virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) override {}
virtual void signal_system_menu_action(const wchar_t* name) override {}
};
73 changes: 73 additions & 0 deletions src/modules/powerlauncher/PowerLauncher/PowerLauncher.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (United States) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE
BEGIN
"resource.h\0"
END

2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END

3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END

#endif // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// String Table
//


#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
STRINGTABLE
BEGIN
IDS_GENERAL_DESCRIPTION L"Power Launcher";
IDS_MODULE_NAME L"Power Launcher";
IDS_ICON_KEY_NAME L"pt-power-launcher";
END


#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

Loading