├── Helpers
├── Helpers.rc
├── Helpers.vcxproj.user
├── Helpers.h
├── dllmain.cpp
├── ..svnbridge
│ ├── .svnbridge
│ ├── Helpers.aps
│ └── Helpers.rc
├── targetver.h
├── stdafx.h
├── resource.h
├── Helpers.vcxproj.filters
└── Helpers.cpp
├── GlobalShellHook
├── GlobalShellHook.rc
├── GlobalShellHook.vcxproj.user
├── GlobalShellHook.h
├── targetver.h
├── resource.h
├── stdafx.h
├── dllmain.c
├── GlobalShellHook.c
└── GlobalShellHook.vcxproj.filters
├── SystemTrayHook
├── SystemTrayHook.rc
├── SystemTrayHook.vcxproj.user
├── ..svnbridge
│ ├── .svnbridge
│ ├── SystemTrayHook.aps
│ └── SystemTrayHook.rc
├── SystemTrayHook.h
├── targetver.h
├── dllmain.c
├── stdafx.h
├── resource.h
├── SystemTrayHook.c
└── SystemTrayHook.vcxproj.filters
├── Windawesome
├── Images
│ ├── Icon missing.png
│ └── ..svnbridge
│ │ └── Icon missing.png
├── app.config
├── IPlugin.cs
├── ..svnbridge
│ └── .svnbridge
├── Properties
│ ├── Settings.settings
│ ├── Settings.Designer.cs
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ └── Resources.resx
├── IBar.cs
├── Windawesome.csproj.user
├── ILayout.cs
├── FloatingLayout.cs
├── UpdateChecker.cs
├── SeparatorWidget.cs
├── InputLanguageChangerPlugin.cs
├── IWidget.cs
├── SystemAndProcessInformation.cs
├── HashMultiSet.cs
├── CurrentlyPlayingWidget.cs
├── RamMonitorWidget.cs
├── CPUMonitorWidget.cs
├── LayoutWidget.cs
├── NetworkMonitorWidget.cs
├── Program.cs
├── LaptopBatteryMonitorWidget.cs
├── FullScreenLayout.cs
├── LanguageBarWidget.cs
├── LoggerPlugin.cs
├── Utilities.cs
├── SystemSettingsChanger.cs
└── WorkspacesWidget.cs
├── WindowSubclassing
├── WindowSubclassing.aps
├── WindowSubclassing.rc
├── WindowSubclassing.vcxproj.user
├── ..svnbridge
│ ├── .svnbridge
│ ├── WindowSubclassing.aps
│ └── WindowSubclassing.rc
├── WindowSubclassing.h
├── stdafx.cpp
├── targetver.h
├── stdafx.h
├── resource.h
├── dllmain.c
├── WindowSubclassing.vcxproj.filters
└── WindowSubclassing.c
├── app_version.xml
├── lib
├── Needed files.txt
└── ..svnbridge
│ └── .svnbridge
├── TileLayout
├── ..svnbridge
│ └── .svnbridge
├── Properties
│ └── AssemblyInfo.cs
├── TileLayout.csproj
└── TileLayout.cs
├── ShortcutsManager
├── ..svnbridge
│ └── .svnbridge
├── Properties
│ └── AssemblyInfo.cs
├── ShortcutsManager.csproj
└── ShortcutsManager.cs
├── WindowSubclassingCSharp
├── ..svnbridge
│ └── .svnbridge
├── Properties
│ └── AssemblyInfo.cs
├── WindowSubclassing.cs
└── WindowSubclassingCSharp.csproj
├── CONTRIBUTORS.txt
├── .hgignore
├── ..svnbridge
└── .svnbridge
├── README.md
├── Widgets
└── DateTimeWidget.rb
├── Config
├── 2-Program Rules.py
├── 1-General Settings.py
└── 3-Hotkeys.rb
├── Docs
└── API.txt
└── Windawesome.sln
/Helpers/Helpers.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boris-petrov/windawesome/HEAD/Helpers/Helpers.rc
--------------------------------------------------------------------------------
/GlobalShellHook/GlobalShellHook.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boris-petrov/windawesome/HEAD/GlobalShellHook/GlobalShellHook.rc
--------------------------------------------------------------------------------
/SystemTrayHook/SystemTrayHook.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boris-petrov/windawesome/HEAD/SystemTrayHook/SystemTrayHook.rc
--------------------------------------------------------------------------------
/Windawesome/Images/Icon missing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boris-petrov/windawesome/HEAD/Windawesome/Images/Icon missing.png
--------------------------------------------------------------------------------
/WindowSubclassing/WindowSubclassing.aps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boris-petrov/windawesome/HEAD/WindowSubclassing/WindowSubclassing.aps
--------------------------------------------------------------------------------
/WindowSubclassing/WindowSubclassing.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boris-petrov/windawesome/HEAD/WindowSubclassing/WindowSubclassing.rc
--------------------------------------------------------------------------------
/app_version.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1.4.2
4 | http://windawesome.codeplex.com
5 |
6 |
--------------------------------------------------------------------------------
/lib/Needed files.txt:
--------------------------------------------------------------------------------
1 | IronPython.dll
2 | IronPython.Modules.dll
3 | IronRuby.dll
4 | IronRuby.Libraries.dll
5 | Microsoft.Dynamic.dll
6 | Microsoft.Scripting.dll
7 |
--------------------------------------------------------------------------------
/Helpers/Helpers.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/GlobalShellHook/GlobalShellHook.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/SystemTrayHook/SystemTrayHook.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/Windawesome/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/WindowSubclassing/WindowSubclassing.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/Windawesome/IPlugin.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Windawesome
3 | {
4 | public interface IPlugin
5 | {
6 | void InitializePlugin(Windawesome windawesome);
7 |
8 | void Dispose();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Helpers/Helpers.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | #define HELPERS_API __declspec(dllexport)
5 |
6 | extern "C" {
7 | HELPERS_API void __cdecl RunApplicationNonElevated(const WCHAR*, const WCHAR*);
8 | }
9 |
10 | #undef HELPERS_API
11 |
--------------------------------------------------------------------------------
/Helpers/dllmain.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "stdafx.h"
3 |
4 | BOOL APIENTRY DllMain( HMODULE hModule,
5 | DWORD ul_reason_for_call,
6 | LPVOID lpReserved
7 | )
8 | {
9 | return TRUE;
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/Helpers/..svnbridge/.svnbridge:
--------------------------------------------------------------------------------
1 | svn:ignorebin
2 |
--------------------------------------------------------------------------------
/SystemTrayHook/..svnbridge/.svnbridge:
--------------------------------------------------------------------------------
1 | svn:ignorebin
2 |
--------------------------------------------------------------------------------
/WindowSubclassing/..svnbridge/.svnbridge:
--------------------------------------------------------------------------------
1 | svn:ignorebin
2 |
--------------------------------------------------------------------------------
/SystemTrayHook/SystemTrayHook.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | #define SYSTEMTRAYHOOK_API __declspec(dllexport)
5 |
6 | SYSTEMTRAYHOOK_API BOOL __cdecl RegisterSystemTrayHook(HWND hWnd);
7 | SYSTEMTRAYHOOK_API BOOL __cdecl UnregisterSystemTrayHook();
8 |
9 | #undef SYSTEMTRAYHOOK_API
10 |
--------------------------------------------------------------------------------
/TileLayout/..svnbridge/.svnbridge:
--------------------------------------------------------------------------------
1 | svn:ignorebin
2 | obj
3 |
--------------------------------------------------------------------------------
/Windawesome/..svnbridge/.svnbridge:
--------------------------------------------------------------------------------
1 | svn:ignorebin
2 | obj
3 |
--------------------------------------------------------------------------------
/Helpers/..svnbridge/Helpers.aps:
--------------------------------------------------------------------------------
1 | svn:mime-typeapplication/octet-stream
--------------------------------------------------------------------------------
/Helpers/..svnbridge/Helpers.rc:
--------------------------------------------------------------------------------
1 | svn:mime-typeapplication/octet-stream
--------------------------------------------------------------------------------
/ShortcutsManager/..svnbridge/.svnbridge:
--------------------------------------------------------------------------------
1 | svn:ignorebin
2 | obj
3 |
--------------------------------------------------------------------------------
/GlobalShellHook/GlobalShellHook.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | #define GLOBALSHELLHOOK_API __declspec(dllexport)
5 |
6 | GLOBALSHELLHOOK_API BOOL __cdecl RegisterGlobalShellHook(HWND handle);
7 | GLOBALSHELLHOOK_API BOOL __cdecl UnregisterGlobalShellHook();
8 |
9 | #undef GLOBALSHELLHOOK_API
10 |
--------------------------------------------------------------------------------
/Windawesome/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/WindowSubclassingCSharp/..svnbridge/.svnbridge:
--------------------------------------------------------------------------------
1 | svn:ignorebin
2 | obj
3 |
--------------------------------------------------------------------------------
/SystemTrayHook/..svnbridge/SystemTrayHook.aps:
--------------------------------------------------------------------------------
1 | svn:mime-typeapplication/octet-stream
--------------------------------------------------------------------------------
/SystemTrayHook/..svnbridge/SystemTrayHook.rc:
--------------------------------------------------------------------------------
1 | svn:mime-typeapplication/octet-stream
--------------------------------------------------------------------------------
/Windawesome/Images/..svnbridge/Icon missing.png:
--------------------------------------------------------------------------------
1 | svn:mime-typeapplication/octet-stream
--------------------------------------------------------------------------------
/WindowSubclassing/..svnbridge/WindowSubclassing.aps:
--------------------------------------------------------------------------------
1 | svn:mime-typeapplication/octet-stream
--------------------------------------------------------------------------------
/WindowSubclassing/..svnbridge/WindowSubclassing.rc:
--------------------------------------------------------------------------------
1 | svn:mime-typeapplication/octet-stream
--------------------------------------------------------------------------------
/WindowSubclassing/WindowSubclassing.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | #define WINDOWSUBCLASSING_API __declspec(dllexport)
5 |
6 | WINDOWSUBCLASSING_API BOOL __cdecl SubclassWindow(HWND hWnd, HWND window);
7 | WINDOWSUBCLASSING_API BOOL __cdecl UnsubclassWindow(HWND window);
8 |
9 | #undef WINDOWSUBCLASSING_API
10 |
--------------------------------------------------------------------------------
/CONTRIBUTORS.txt:
--------------------------------------------------------------------------------
1 | THANKS TO:
2 |
3 | weiwen - network monitor widget implementation
4 | mkocubinski - xmonad-like functionality for multiple monitors
5 | vOSHoHpC - RAM monitor widget implementation
6 | daedric - reported a language bar widget bug
7 | joankaradimov - system tray widget refactoring and IronPython/IronRuby integration
--------------------------------------------------------------------------------
/.hgignore:
--------------------------------------------------------------------------------
1 | lib/IronPython.Modules.dll
2 | lib/IronPython.dll
3 | lib/IronRuby.Libraries.dll
4 | lib/IronRuby.dll
5 | lib/Microsoft.Dynamic.dll
6 | lib/Microsoft.Scripting.dll
7 | bin/x64
8 | ShortcutsManager/obj
9 | TileLayout/obj
10 | Windawesome/obj
11 | WindowSubclassingCSharp/obj
12 | Windawesome.opensdf
13 | Windawesome.sdf
14 |
--------------------------------------------------------------------------------
/WindowSubclassing/stdafx.cpp:
--------------------------------------------------------------------------------
1 | // stdafx.cpp : source file that includes just the standard includes
2 | // GlobalHooksCPP.pch will be the pre-compiled header
3 | // stdafx.obj will contain the pre-compiled type information
4 |
5 | #include "stdafx.h"
6 |
7 | // TODO: reference any additional headers you need in STDAFX.H
8 | // and not in this file
9 |
--------------------------------------------------------------------------------
/Helpers/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // Including SDKDDKVer.h defines the highest available Windows platform.
4 |
5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
7 |
8 | #include
9 |
--------------------------------------------------------------------------------
/GlobalShellHook/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // Including SDKDDKVer.h defines the highest available Windows platform.
4 |
5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
7 |
8 | #include
9 |
--------------------------------------------------------------------------------
/SystemTrayHook/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // Including SDKDDKVer.h defines the highest available Windows platform.
4 |
5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
7 |
8 | #include
9 |
--------------------------------------------------------------------------------
/WindowSubclassing/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // Including SDKDDKVer.h defines the highest available Windows platform.
4 |
5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
7 |
8 | #include
9 |
--------------------------------------------------------------------------------
/Helpers/stdafx.h:
--------------------------------------------------------------------------------
1 | // stdafx.h : include file for standard system include files,
2 | // or project specific include files that are used frequently, but
3 | // are changed infrequently
4 | //
5 |
6 | #pragma once
7 |
8 | #include "targetver.h"
9 |
10 | // Windows Header Files:
11 | #include
12 | #include
13 | #include
14 | #include
15 |
--------------------------------------------------------------------------------
/lib/..svnbridge/.svnbridge:
--------------------------------------------------------------------------------
1 | svn:ignoreIronPython.Modules.dll
2 | IronPython.dll
3 | IronRuby.Libraries.dll
4 | IronRuby.dll
5 | Microsoft.Dynamic.dll
6 | Microsoft.Scripting.dll
7 |
--------------------------------------------------------------------------------
/WindowSubclassing/stdafx.h:
--------------------------------------------------------------------------------
1 | // stdafx.h : include file for standard system include files,
2 | // or project specific include files that are used frequently, but
3 | // are changed infrequently
4 | //
5 |
6 | #pragma once
7 |
8 | #include "targetver.h"
9 |
10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
11 | // Windows Header Files:
12 | #include
13 |
--------------------------------------------------------------------------------
/SystemTrayHook/dllmain.c:
--------------------------------------------------------------------------------
1 |
2 | #include "stdafx.h"
3 |
4 | extern HINSTANCE hInstance;
5 |
6 | BOOL APIENTRY DllMain( HMODULE hModule,
7 | DWORD ul_reason_for_call,
8 | LPVOID lpReserved
9 | )
10 | {
11 | switch (ul_reason_for_call)
12 | {
13 | case DLL_PROCESS_ATTACH:
14 | hInstance = hModule;
15 | break;
16 | }
17 | return TRUE;
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/SystemTrayHook/stdafx.h:
--------------------------------------------------------------------------------
1 | // stdafx.h : include file for standard system include files,
2 | // or project specific include files that are used frequently, but
3 | // are changed infrequently
4 | //
5 |
6 | #pragma once
7 |
8 | #include "targetver.h"
9 |
10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
11 | // Windows Header Files:
12 | #include
13 | #include
14 |
--------------------------------------------------------------------------------
/Windawesome/IBar.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Windawesome
4 | {
5 | public interface IBar
6 | {
7 | void InitializeBar(Windawesome windawesome);
8 | void Dispose();
9 |
10 | IntPtr Handle { get; }
11 |
12 | Monitor Monitor { get; }
13 |
14 | int GetBarHeight();
15 |
16 | void OnClientWidthChanging(int newWidth);
17 |
18 | void Show();
19 | void Hide();
20 |
21 | void Refresh();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Helpers/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by Helpers.rc
4 |
5 | // Next default values for new objects
6 | //
7 | #ifdef APSTUDIO_INVOKED
8 | #ifndef APSTUDIO_READONLY_SYMBOLS
9 | #define _APS_NEXT_RESOURCE_VALUE 101
10 | #define _APS_NEXT_COMMAND_VALUE 40001
11 | #define _APS_NEXT_CONTROL_VALUE 1001
12 | #define _APS_NEXT_SYMED_VALUE 101
13 | #endif
14 | #endif
15 |
--------------------------------------------------------------------------------
/SystemTrayHook/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by SystemTrayHook.rc
4 |
5 | // Next default values for new objects
6 | //
7 | #ifdef APSTUDIO_INVOKED
8 | #ifndef APSTUDIO_READONLY_SYMBOLS
9 | #define _APS_NEXT_RESOURCE_VALUE 101
10 | #define _APS_NEXT_COMMAND_VALUE 40001
11 | #define _APS_NEXT_CONTROL_VALUE 1001
12 | #define _APS_NEXT_SYMED_VALUE 101
13 | #endif
14 | #endif
15 |
--------------------------------------------------------------------------------
/WindowSubclassing/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by WindowSubclassing.rc
4 |
5 | // Next default values for new objects
6 | //
7 | #ifdef APSTUDIO_INVOKED
8 | #ifndef APSTUDIO_READONLY_SYMBOLS
9 | #define _APS_NEXT_RESOURCE_VALUE 101
10 | #define _APS_NEXT_COMMAND_VALUE 40001
11 | #define _APS_NEXT_CONTROL_VALUE 1001
12 | #define _APS_NEXT_SYMED_VALUE 101
13 | #endif
14 | #endif
15 |
--------------------------------------------------------------------------------
/GlobalShellHook/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by GlobalShellHook.rc
4 | //
5 |
6 | // Next default values for new objects
7 | //
8 | #ifdef APSTUDIO_INVOKED
9 | #ifndef APSTUDIO_READONLY_SYMBOLS
10 | #define _APS_NEXT_RESOURCE_VALUE 101
11 | #define _APS_NEXT_COMMAND_VALUE 40001
12 | #define _APS_NEXT_CONTROL_VALUE 1001
13 | #define _APS_NEXT_SYMED_VALUE 101
14 | #endif
15 | #endif
16 |
--------------------------------------------------------------------------------
/GlobalShellHook/stdafx.h:
--------------------------------------------------------------------------------
1 | // stdafx.h : include file for standard system include files,
2 | // or project specific include files that are used frequently, but
3 | // are changed infrequently
4 | //
5 |
6 | #pragma once
7 |
8 | #include "targetver.h"
9 |
10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
11 | // Windows Header Files:
12 | #include
13 |
14 |
15 |
16 | // TODO: reference additional headers your program requires here
17 |
--------------------------------------------------------------------------------
/Windawesome/Windawesome.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | publish\
5 |
6 |
7 |
8 |
9 |
10 | en-US
11 | false
12 |
13 |
--------------------------------------------------------------------------------
/GlobalShellHook/dllmain.c:
--------------------------------------------------------------------------------
1 | // dllmain.cpp : Defines the entry point for the DLL application.
2 | #include "stdafx.h"
3 |
4 | extern HINSTANCE hInstance;
5 |
6 | BOOL APIENTRY DllMain( HMODULE hModule,
7 | DWORD ul_reason_for_call,
8 | LPVOID lpReserved
9 | )
10 | {
11 | switch (ul_reason_for_call)
12 | {
13 | case DLL_PROCESS_ATTACH:
14 | hInstance = hModule;
15 | break;
16 | case DLL_THREAD_ATTACH:
17 | case DLL_THREAD_DETACH:
18 | case DLL_PROCESS_DETACH:
19 | break;
20 | }
21 | return TRUE;
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/WindowSubclassing/dllmain.c:
--------------------------------------------------------------------------------
1 |
2 | #include "stdafx.h"
3 |
4 | extern HINSTANCE hInstance;
5 | extern UINT START_WINDOW_PROC_MESSAGE;
6 | extern UINT STOP_WINDOW_PROC_MESSAGE;
7 |
8 | BOOL APIENTRY DllMain( HMODULE hModule,
9 | DWORD ul_reason_for_call,
10 | LPVOID lpReserved
11 | )
12 | {
13 | switch (ul_reason_for_call)
14 | {
15 | case DLL_PROCESS_ATTACH:
16 | hInstance = hModule;
17 | if (!START_WINDOW_PROC_MESSAGE)
18 | {
19 | START_WINDOW_PROC_MESSAGE = RegisterWindowMessage(TEXT("START_WINDOW_PROC"));
20 | STOP_WINDOW_PROC_MESSAGE = RegisterWindowMessage(TEXT("STOP_WINDOW_PROC"));
21 | }
22 | break;
23 | }
24 | return TRUE;
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/..svnbridge/.svnbridge:
--------------------------------------------------------------------------------
1 | svn:ignore*.sdf
2 | Old
3 | Windawesome.suo
4 | bin
5 | lib
6 | svn:ignore*.sdf
7 | Old
8 | Windawesome.opensdf
9 | Windawesome.suo
10 | bin
11 | lib
12 | svn:ignore*.sdf
13 | Old
14 | Windawesome.opensdf
15 | Windawesome.suo
16 | bin
17 | ipch
18 | lib
19 | svn:ignore*.sdf
20 | Old
21 | Windawesome.5.1.ReSharper
22 | Windawesome.5.1.ReSharper.user
23 | Windawesome.opensdf
24 | Windawesome.suo
25 | bin
26 | ipch
27 | lib
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Windawesome (pronounced - contrary to what you would expect from the way it is written - Windows-om, not Wind-awesome) is a highly customizable tiling/dynamic window manager with multi-monitor support for Windows, which works on top of explorer.exe and *not* as a shell replacement. It is heavily inspired by [bug.n](http://www.autohotkey.net/~joten/bug.n.html), but tries to go further. Windawesome is (mostly) written in C# and is scriptable and pluggable in IronRuby, IronPython and any .NET language that compiles down to an assembly. Requires .NET Framework 4 Client Profile, Visual C++ 2010 Redistributable and IronRuby/IronPython DLLs. The main bundle comes with 3 configuration files (2 in Python, 1 in Ruby), 3 layouts (2 built-in and one as a C# DLL), a couple of Plugins and many Widgets, one of which is written in Ruby. Works with 32- and 64-bit versions of Windows XP, Vista, 7, 8 and 8.1. Goes under the GNU General Public License version 2.
2 |
--------------------------------------------------------------------------------
/Windawesome/ILayout.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Windawesome
3 | {
4 | public interface ILayout
5 | {
6 | string LayoutSymbol();
7 | string LayoutName();
8 |
9 | void Initialize(Workspace workspace);
10 | void Dispose();
11 |
12 | /*
13 | * Should return whether Windawesome should restore a shared window's position if there
14 | * are no changes to the workspace. If there are, Reposition will be called anyway
15 | */
16 | bool ShouldSaveAndRestoreSharedWindowsPosition();
17 |
18 | /*
19 | * This is guaranteed to be called only when the workspace is visible
20 | */
21 | void Reposition();
22 |
23 | /*
24 | * The next four functions can be called when the workspace is visible, as well
25 | * as invisible
26 | */
27 | void WindowMinimized(Window window);
28 | void WindowRestored(Window window);
29 | void WindowCreated(Window window);
30 | void WindowDestroyed(Window window);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Windawesome/FloatingLayout.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Windawesome
3 | {
4 | public sealed class FloatingLayout : ILayout
5 | {
6 | #region ILayout Members
7 |
8 | string ILayout.LayoutSymbol()
9 | {
10 | return "><>";
11 | }
12 |
13 | public string LayoutName()
14 | {
15 | return "Floating";
16 | }
17 |
18 | void ILayout.Initialize(Workspace workspace)
19 | {
20 | }
21 |
22 | void ILayout.Dispose()
23 | {
24 | }
25 |
26 | bool ILayout.ShouldSaveAndRestoreSharedWindowsPosition()
27 | {
28 | return true;
29 | }
30 |
31 | void ILayout.Reposition()
32 | {
33 | }
34 |
35 | void ILayout.WindowMinimized(Window window)
36 | {
37 | }
38 |
39 | void ILayout.WindowRestored(Window window)
40 | {
41 | }
42 |
43 | void ILayout.WindowCreated(Window window)
44 | {
45 | }
46 |
47 | void ILayout.WindowDestroyed(Window window)
48 | {
49 | }
50 |
51 | #endregion
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Windawesome/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.1
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Windawesome.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/GlobalShellHook/GlobalShellHook.c:
--------------------------------------------------------------------------------
1 | // GlobalShellHook.cpp : Defines the exported functions for the DLL application.
2 | //
3 |
4 | #include "stdafx.h"
5 | #include "GlobalShellHook.h"
6 |
7 | #pragma data_seg(".shared")
8 | #pragma comment(linker, "/SECTION:.shared,RWS")
9 |
10 | HWND applicationHandle = NULL;
11 | UINT globalShellHookMessage = 0;
12 |
13 | #pragma data_seg()
14 |
15 | HINSTANCE hInstance = NULL;
16 | static HHOOK hook = NULL;
17 |
18 | static LRESULT CALLBACK ShellHookProc(int code, WPARAM wParam, LPARAM lParam);
19 |
20 | BOOL RegisterGlobalShellHook(HWND hWnd)
21 | {
22 | applicationHandle = hWnd;
23 |
24 | globalShellHookMessage = RegisterWindowMessage(TEXT("GLOBAL_SHELL_HOOK"));
25 |
26 | return (hook = SetWindowsHookEx(WH_SHELL, (HOOKPROC) ShellHookProc, hInstance, 0)) != NULL;
27 | }
28 |
29 | BOOL UnregisterGlobalShellHook()
30 | {
31 | return hook != NULL ? UnhookWindowsHookEx(hook) : TRUE;
32 | }
33 |
34 | static LRESULT CALLBACK ShellHookProc(int code, WPARAM wParam, LPARAM lParam)
35 | {
36 | if (code == HSHELL_LANGUAGE)
37 | {
38 | PostMessage(applicationHandle, globalShellHookMessage, wParam, lParam);
39 | }
40 |
41 | return CallNextHookEx(NULL, code, wParam, lParam);
42 | }
43 |
--------------------------------------------------------------------------------
/Windawesome/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("Windawesome")]
8 | [assembly: AssemblyDescription("Dynamic Window Manager for Windows")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("Boris Petrov")]
11 | [assembly: AssemblyProduct("Windawesome")]
12 | [assembly: AssemblyCopyright("Copyleft 2012")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("8b54cfff-9ef6-450f-8d22-5ce2c322c2d1")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("1.4.2.0")]
35 | [assembly: AssemblyFileVersion("1.4.2.0")]
36 |
--------------------------------------------------------------------------------
/TileLayout/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Windawesome Tile Layout")]
9 | [assembly: AssemblyDescription("Tile Layout for Windawesome WM")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Boris Petrov")]
12 | [assembly: AssemblyProduct("Windawesome Tile Layout")]
13 | [assembly: AssemblyCopyright("Copyleft 2012")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("10c42791-b4a2-4434-a0ab-6afeec30a1d1")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.4.2.0")]
36 | [assembly: AssemblyFileVersion("1.4.0.0")]
37 |
--------------------------------------------------------------------------------
/WindowSubclassingCSharp/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Windawesome Window Subclassing Plugin")]
9 | [assembly: AssemblyDescription("A Plugin for Windawesome WM")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Boris Petrov")]
12 | [assembly: AssemblyProduct("Windawesome Window Subclassing Plugin")]
13 | [assembly: AssemblyCopyright("Copyright © 2011")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("c363a771-9bf4-4bea-a878-b4896ffc2db9")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.18.0")]
36 | [assembly: AssemblyFileVersion("1.0.18.0")]
37 |
--------------------------------------------------------------------------------
/ShortcutsManager/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Windawesome ShortcutsManager Plugin")]
9 | [assembly: AssemblyDescription("Plugin for keyboard shortcuts for Windawesome WM")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Boris Petrov")]
12 | [assembly: AssemblyProduct("Windawesome ShortcutsManager Plugin")]
13 | [assembly: AssemblyCopyright("Copyleft 2012")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("32df9c5e-9c0f-465b-8778-d3391234e897")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.4.2.0")]
36 | [assembly: AssemblyFileVersion("1.4.0.0")]
37 |
--------------------------------------------------------------------------------
/Helpers/Helpers.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Header Files
20 |
21 |
22 | Header Files
23 |
24 |
25 | Header Files
26 |
27 |
28 | Header Files
29 |
30 |
31 |
32 |
33 | Source Files
34 |
35 |
36 | Source Files
37 |
38 |
39 |
40 |
41 | Resource Files
42 |
43 |
44 |
--------------------------------------------------------------------------------
/SystemTrayHook/SystemTrayHook.c:
--------------------------------------------------------------------------------
1 |
2 | #include "stdafx.h"
3 | #include "SystemTrayHook.h"
4 |
5 | #pragma data_seg(".shared")
6 | #pragma comment(linker, "/SECTION:.shared,RWS")
7 |
8 | HWND applicationHandle = NULL;
9 |
10 | #pragma data_seg()
11 |
12 | static HHOOK hook = NULL;
13 | HINSTANCE hInstance = NULL;
14 |
15 | static LRESULT CALLBACK HookCallback(int code, WPARAM wParam, LPARAM lParam);
16 |
17 | BOOL RegisterSystemTrayHook(HWND hWnd)
18 | {
19 | HWND hShell = FindWindow(L"Shell_TrayWnd", NULL);
20 | DWORD shellThread = GetWindowThreadProcessId(hShell, NULL);
21 |
22 | applicationHandle = hWnd;
23 |
24 | return (hook = SetWindowsHookEx(WH_CALLWNDPROCRET, (HOOKPROC) HookCallback, hInstance, shellThread)) != NULL;
25 | }
26 |
27 | BOOL UnregisterSystemTrayHook()
28 | {
29 | return hook != NULL ? UnhookWindowsHookEx(hook) : TRUE;
30 | }
31 |
32 | #define SH_TRAY_DATA 1
33 |
34 | typedef struct
35 | {
36 | DWORD dwHz;
37 | DWORD dwMessage;
38 | NOTIFYICONDATA nid; // this is a 64-bit structure, when running in 64-bit mode, but should be 32!
39 | } SHELLTRAYDATA;
40 |
41 | static LRESULT CALLBACK HookCallback(int code, WPARAM wParam, LPARAM lParam)
42 | {
43 | if (code >= 0)
44 | {
45 | CWPRETSTRUCT *pInfo = (CWPRETSTRUCT*) lParam;
46 |
47 | if (pInfo->message == WM_COPYDATA)
48 | {
49 | COPYDATASTRUCT* copyDataStruct = (COPYDATASTRUCT*) pInfo->lParam;
50 | if (copyDataStruct->dwData == SH_TRAY_DATA &&
51 | ((SHELLTRAYDATA*) copyDataStruct->lpData)->dwHz == 0x34753423)
52 | {
53 | SendMessageTimeout(applicationHandle, WM_COPYDATA, pInfo->wParam, pInfo->lParam,
54 | SMTO_ABORTIFHUNG, 10000, NULL);
55 | }
56 | }
57 | }
58 |
59 | return CallNextHookEx(NULL, code, wParam, lParam);
60 | }
61 |
--------------------------------------------------------------------------------
/SystemTrayHook/SystemTrayHook.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Header Files
20 |
21 |
22 | Header Files
23 |
24 |
25 | Header Files
26 |
27 |
28 | Header Files
29 |
30 |
31 |
32 |
33 | Source Files
34 |
35 |
36 | Source Files
37 |
38 |
39 |
40 |
41 | Resource Files
42 |
43 |
44 |
--------------------------------------------------------------------------------
/WindowSubclassing/WindowSubclassing.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Header Files
20 |
21 |
22 | Header Files
23 |
24 |
25 | Header Files
26 |
27 |
28 | Header Files
29 |
30 |
31 |
32 |
33 | Source Files
34 |
35 |
36 | Source Files
37 |
38 |
39 |
40 |
41 | Resource Files
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Windawesome/UpdateChecker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using System.Windows.Forms;
4 | using System.Xml;
5 |
6 | namespace Windawesome
7 | {
8 | public static class UpdateChecker
9 | {
10 | public static void CheckForUpdate()
11 | {
12 | const string xmlUrl = "https://raw.githubusercontent.com/boris-petrov/windawesome/master/app_version.xml";
13 |
14 | Task.Factory.StartNew(() =>
15 | {
16 | Version newVersion = null;
17 | string url = null;
18 |
19 | try
20 | {
21 | var xmlDocument = new XmlDocument();
22 | xmlDocument.Load(xmlUrl);
23 |
24 | var versionNode = xmlDocument.SelectNodes("/Windawesome/version")[0];
25 | newVersion = new Version(versionNode.InnerText);
26 |
27 | var urlNode = xmlDocument.SelectNodes("/Windawesome/url")[0];
28 | url = urlNode.InnerText;
29 | }
30 | catch
31 | {
32 | }
33 |
34 | return Tuple.Create(newVersion, url);
35 | }).ContinueWith(t =>
36 | {
37 | var newVersion = t.Result.Item1;
38 | var url = t.Result.Item2;
39 |
40 | if (newVersion != null)
41 | {
42 | var currentVersion = new Version(Application.ProductVersion);
43 |
44 | if (currentVersion.CompareTo(newVersion) < 0)
45 | {
46 | var result = MessageBox.Show(
47 | "There is a new version of Windawesome. Would you like to open the website to download it?",
48 | "New version available",
49 | MessageBoxButtons.YesNo,
50 | MessageBoxIcon.Question);
51 | if (result == DialogResult.Yes)
52 | {
53 | Utilities.RunApplication(url);
54 | }
55 | }
56 | }
57 | }, TaskScheduler.FromCurrentSynchronizationContext());
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Windawesome/SeparatorWidget.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 | using System.Windows.Forms;
4 |
5 | namespace Windawesome
6 | {
7 | public sealed class SeparatorWidget : IFixedWidthWidget
8 | {
9 | private Label label;
10 | private bool isLeft;
11 | private readonly string separator;
12 | private readonly Color backgroundColor;
13 | private readonly Color foregroundColor;
14 |
15 | public SeparatorWidget(string separator = "|", Color? backgroundColor = null, Color? foregroundColor = null)
16 | {
17 | this.separator = separator;
18 |
19 | this.backgroundColor = backgroundColor ?? Color.White;
20 | this.foregroundColor = foregroundColor ?? Color.Black;
21 | }
22 |
23 | #region IWidget Members
24 |
25 | void IWidget.StaticInitializeWidget(Windawesome windawesome)
26 | {
27 | }
28 |
29 | void IWidget.InitializeWidget(Bar bar)
30 | {
31 | label = bar.CreateLabel(separator, 0);
32 | label.BackColor = backgroundColor;
33 | label.ForeColor = foregroundColor;
34 | label.TextAlign = ContentAlignment.MiddleCenter;
35 | }
36 |
37 | IEnumerable IFixedWidthWidget.GetInitialControls(bool isLeft)
38 | {
39 | this.isLeft = isLeft;
40 |
41 | return new[] { label };
42 | }
43 |
44 | public void RepositionControls(int left, int right)
45 | {
46 | this.label.Location = this.isLeft ? new Point(left, 0) : new Point(right - this.label.Width, 0);
47 | }
48 |
49 | int IWidget.GetLeft()
50 | {
51 | return label.Left;
52 | }
53 |
54 | int IWidget.GetRight()
55 | {
56 | return label.Right;
57 | }
58 |
59 | void IWidget.StaticDispose()
60 | {
61 | }
62 |
63 | void IWidget.Dispose()
64 | {
65 | }
66 |
67 | void IWidget.Refresh()
68 | {
69 | }
70 |
71 | #endregion
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/GlobalShellHook/GlobalShellHook.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | Header Files
23 |
24 |
25 | Header Files
26 |
27 |
28 | Header Files
29 |
30 |
31 | Header Files
32 |
33 |
34 |
35 |
36 | Source Files
37 |
38 |
39 | Source Files
40 |
41 |
42 |
43 |
44 | Resource Files
45 |
46 |
47 |
--------------------------------------------------------------------------------
/Windawesome/InputLanguageChangerPlugin.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Windawesome
5 | {
6 | public class InputLanguageChangerPlugin : IPlugin
7 | {
8 | private readonly HashSet classNamesSet;
9 | private readonly Dictionary inputLanguages;
10 | private IntPtr currentForeground;
11 |
12 | public InputLanguageChangerPlugin(IEnumerable windowClassNames)
13 | {
14 | classNamesSet = new HashSet(windowClassNames);
15 | inputLanguages = new Dictionary(5);
16 |
17 | Workspace.WindowActivatedEvent += OnWindowActivatedEvent;
18 | }
19 |
20 | private void OnWindowActivatedEvent(IntPtr hWnd)
21 | {
22 | if (currentForeground != IntPtr.Zero)
23 | {
24 | SaveLayoutForWindow(currentForeground);
25 | }
26 |
27 | var className = NativeMethods.GetWindowClassName(hWnd);
28 |
29 | if (classNamesSet.Contains(className))
30 | {
31 | IntPtr keyboardLayout;
32 | if (inputLanguages.TryGetValue(hWnd, out keyboardLayout))
33 | {
34 | NativeMethods.SendNotifyMessage(hWnd, NativeMethods.WM_INPUTLANGCHANGEREQUEST,
35 | UIntPtr.Zero, keyboardLayout);
36 | }
37 | else
38 | {
39 | SaveLayoutForWindow(hWnd);
40 | }
41 |
42 | currentForeground = hWnd;
43 | }
44 | else
45 | {
46 | currentForeground = IntPtr.Zero;
47 | }
48 | }
49 |
50 | private void SaveLayoutForWindow(IntPtr window)
51 | {
52 | var keyboardLayout = NativeMethods.GetKeyboardLayout(
53 | NativeMethods.GetWindowThreadProcessId(window, IntPtr.Zero));
54 |
55 | inputLanguages[window] = keyboardLayout;
56 | }
57 |
58 | #region IPlugin Members
59 |
60 | void IPlugin.InitializePlugin(Windawesome windawesome)
61 | {
62 | }
63 |
64 | void IPlugin.Dispose()
65 | {
66 | }
67 |
68 | #endregion
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Helpers/Helpers.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "stdafx.h"
3 | #include "Helpers.h"
4 |
5 | static IShellDispatch2 *psd = NULL;
6 |
7 | void RunApplicationNonElevated(const WCHAR* path, const WCHAR* arguments)
8 | {
9 | if (psd == NULL)
10 | {
11 | IShellWindows *psw;
12 | if (!SUCCEEDED(CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&psw))))
13 | {
14 | return ;
15 | }
16 | HWND hwnd;
17 | IDispatch* pdisp;
18 | VARIANT vEmpty = {}; // VT_EMPTY
19 | if (S_OK != psw->FindWindowSW(&vEmpty, &vEmpty, SWC_DESKTOP, (long*) &hwnd, SWFO_NEEDDISPATCH, &pdisp))
20 | {
21 | return ;
22 | }
23 | IShellBrowser *psb;
24 |
25 | if (!SUCCEEDED(IUnknown_QueryService(pdisp, SID_STopLevelBrowser, IID_PPV_ARGS(&psb))))
26 | {
27 | return ;
28 | }
29 | IShellView *psv;
30 | psb->QueryActiveShellView(&psv);
31 |
32 | IDispatch *pdispBackground;
33 | if (!SUCCEEDED(psv->GetItemObject(SVGIO_BACKGROUND, IID_PPV_ARGS(&pdispBackground))))
34 | {
35 | return ;
36 | }
37 | IShellFolderViewDual *psfvd;
38 | if (!SUCCEEDED(pdispBackground->QueryInterface(IID_PPV_ARGS(&psfvd))))
39 | {
40 | return ;
41 | }
42 | if (!SUCCEEDED(psfvd->get_Application(&pdisp)))
43 | {
44 | return ;
45 | }
46 | if (!SUCCEEDED(pdisp->QueryInterface(IID_PPV_ARGS(&psd))))
47 | {
48 | return ;
49 | }
50 | }
51 |
52 | VARIANT args;
53 | VariantInit(&args);
54 | args.vt = VT_BSTR;
55 | args.bstrVal = SysAllocString(arguments);
56 |
57 | VARIANT dir;
58 | VariantInit(&dir);
59 |
60 | VARIANT operation;
61 | VariantInit(&operation);
62 | operation.vt = VT_BSTR;
63 | operation.bstrVal = SysAllocString(L"open");
64 |
65 | VARIANT show;
66 | VariantInit(&show);
67 | show.vt = VT_INT;
68 | show.intVal = SW_SHOWDEFAULT;
69 |
70 | BSTR p = SysAllocString(path);
71 | psd->ShellExecuteW(p, args, dir, operation, show);
72 |
73 | SysFreeString(p);
74 | SysFreeString(operation.bstrVal);
75 | SysFreeString(args.bstrVal);
76 | }
77 |
--------------------------------------------------------------------------------
/Widgets/DateTimeWidget.rb:
--------------------------------------------------------------------------------
1 |
2 | class DateTimeWidget
3 | include Windawesome::IFixedWidthWidget
4 | include System
5 | include System::Drawing
6 | include System::Windows::Forms
7 | include System::Linq
8 |
9 | def initialize string, prefix = " ", suffix = " ", back_color = nil, fore_color = nil, update_time = 30000, click = nil
10 | @background_color = back_color || Color.from_argb(0xC0, 0xC0, 0xC0)
11 | @foreground_color = fore_color || Color.black
12 | @string = string
13 | @click = click
14 | @prefix = prefix
15 | @suffix = suffix
16 |
17 | @update_timer = Timer.new
18 | @update_timer.interval = update_time
19 | @update_timer.tick do |s, ea|
20 | old_left = @label.left
21 | old_right = @label.right
22 | old_width = @label.width
23 | @label.text = @prefix + DateTime.now.to_string(@string) + @suffix
24 | @label.width = TextRenderer.measure_text(@label.text, @label.font).width
25 | if old_width != @label.width
26 | self.reposition_controls old_left, old_right
27 | @bar.do_fixed_width_widget_width_changed self
28 | end
29 | end
30 | end
31 |
32 | def static_initialize_widget windawesome; end
33 |
34 | def initialize_widget bar
35 | @bar = bar
36 |
37 | @label = bar.create_label @prefix + DateTime.now.to_string(@string) + @suffix, 0
38 |
39 | @label.text_align = ContentAlignment.middle_center
40 | @label.back_color = @background_color
41 | @label.fore_color = @foreground_color
42 | @label.click.add @click if @click
43 |
44 | @update_timer.start
45 | end
46 |
47 | def get_initial_controls is_left
48 | @is_left = is_left
49 |
50 | Enumerable.repeat @label, 1
51 | end
52 |
53 | def reposition_controls left, right
54 | @label.location = @is_left ? Point.new(left, 0) : Point.new(right - @label.width, 0)
55 | end
56 |
57 | def get_left
58 | @label.left
59 | end
60 |
61 | def get_right
62 | @label.right
63 | end
64 |
65 | def static_dispose; end
66 |
67 | def dispose; end
68 |
69 | def refresh; end
70 |
71 | end
72 |
--------------------------------------------------------------------------------
/Windawesome/IWidget.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Windows.Forms;
3 |
4 | namespace Windawesome
5 | {
6 | public interface IWidget
7 | {
8 | /*
9 | * This is guaranteed to be called exactly once for every Widget type. Useful for
10 | * initializing any static data
11 | */
12 | void StaticInitializeWidget(Windawesome windawesome);
13 |
14 | /*
15 | * This is called for every instance of the Widget and is given its Bar
16 | */
17 | void InitializeWidget(Bar bar);
18 |
19 | void RepositionControls(int left, int right);
20 |
21 | /*
22 | * One should save left and right from the values in RepositionControls
23 | * as the Bar can request them at any point. Even more - the Bar gives -1 for one of the
24 | * two values if the Widget is with FixedWidth, but the Bar will expect valid values for
25 | * both, so make sure you save and initialize them properly
26 | */
27 | int GetLeft();
28 |
29 | int GetRight();
30 |
31 | /*
32 | * This is guaranteed to be called exactly once for every Widget type. Useful for
33 | * disposing of some shared resources
34 | */
35 | void StaticDispose();
36 |
37 | /*
38 | * This is called for every instance of the Widget and is given its Bar
39 | */
40 | void Dispose();
41 |
42 | void Refresh();
43 | }
44 |
45 | public interface ISpanWidget : IWidget
46 | {
47 | /*
48 | * GetInitialControls is called only once in the beginning. After that,
49 | * when any changes occur, RepositionControls will be called
50 | */
51 | IEnumerable GetInitialControls();
52 | }
53 |
54 | public interface IFixedWidthWidget : IWidget
55 | {
56 | /*
57 | * GetInitialControls is called only once in the beginning. After that,
58 | * when any changes occur, RepositionControls will be called
59 | *
60 | * The argument isLeft specifies whether the Widget is on the left or the right side of the Bar
61 | */
62 | IEnumerable GetInitialControls(bool isLeft);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Windawesome/SystemAndProcessInformation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Windows.Forms;
4 |
5 | namespace Windawesome
6 | {
7 | public static class SystemAndProcessInformation
8 | {
9 | public static readonly bool isRunningElevated;
10 | public static readonly bool isAtLeastVista;
11 | public static readonly bool isAtLeast7;
12 | public static readonly Size smallIconSize;
13 | public static readonly IntPtr taskbarButtonsWindowHandle;
14 | public static readonly IntPtr taskbarHandle;
15 | public static readonly IntPtr startButtonHandle;
16 | public static readonly IntPtr trayHandle;
17 | public static readonly IntPtr hiddenTrayHandle;
18 |
19 | static SystemAndProcessInformation()
20 | {
21 | isAtLeastVista = Environment.OSVersion.Version.Major >= 6;
22 | isAtLeast7 = isAtLeastVista && Environment.OSVersion.Version.Minor >= 1;
23 |
24 | isRunningElevated = NativeMethods.IsCurrentProcessElevatedInRespectToShell();
25 |
26 | smallIconSize = SystemInformation.SmallIconSize;
27 |
28 | taskbarButtonsWindowHandle = taskbarHandle;
29 | taskbarButtonsWindowHandle = NativeMethods.FindWindowEx(taskbarButtonsWindowHandle, IntPtr.Zero, "ReBarWindow32", "");
30 | taskbarButtonsWindowHandle = NativeMethods.FindWindowEx(taskbarButtonsWindowHandle, IntPtr.Zero, "MSTaskSwWClass", "Running Applications");
31 |
32 | taskbarHandle = NativeMethods.FindWindow("Shell_TrayWnd", null);
33 | if (isAtLeastVista)
34 | {
35 | startButtonHandle = NativeMethods.FindWindow("Button", "Start");
36 | }
37 |
38 | trayHandle = FindTrayHandle();
39 | if (isAtLeast7)
40 | {
41 | hiddenTrayHandle = FindHiddenTrayHandle();
42 | }
43 | }
44 |
45 | private static IntPtr FindTrayHandle()
46 | {
47 | var hWnd = NativeMethods.FindWindowEx(taskbarHandle, IntPtr.Zero, "TrayNotifyWnd", null);
48 | hWnd = NativeMethods.FindWindowEx(hWnd, IntPtr.Zero, "SysPager", null);
49 | return NativeMethods.FindWindowEx(hWnd, IntPtr.Zero, "ToolbarWindow32", null);
50 | }
51 |
52 | private static IntPtr FindHiddenTrayHandle()
53 | {
54 | var hWnd = NativeMethods.FindWindow("NotifyIconOverflowWindow", null);
55 | return NativeMethods.FindWindowEx(hWnd, IntPtr.Zero, "ToolbarWindow32", null);
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Windawesome/HashMultiSet.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Windawesome
4 | {
5 | public sealed class HashMultiSet : IEnumerable
6 | {
7 | private readonly Dictionary set;
8 | private sealed class BoxedInt
9 | {
10 | public int i = 1;
11 | }
12 |
13 | public HashMultiSet(IEqualityComparer comparer = null)
14 | {
15 | set = new Dictionary(comparer);
16 | }
17 |
18 | public AddResult Add(T item)
19 | {
20 | BoxedInt count;
21 | if (set.TryGetValue(item, out count))
22 | {
23 | count.i++;
24 | return AddResult.Added;
25 | }
26 | else
27 | {
28 | set[item] = new BoxedInt();
29 | return AddResult.AddedFirst;
30 | }
31 | }
32 |
33 | public AddResult AddUnique(T item)
34 | {
35 | if (set.ContainsKey(item))
36 | {
37 | return AddResult.AlreadyContained;
38 | }
39 | else
40 | {
41 | set[item] = new BoxedInt();
42 | return AddResult.AddedFirst;
43 | }
44 | }
45 |
46 | public RemoveResult Remove(T item)
47 | {
48 | BoxedInt count;
49 | if (set.TryGetValue(item, out count))
50 | {
51 | if (count.i == 1)
52 | {
53 | set.Remove(item);
54 | return RemoveResult.RemovedLast;
55 | }
56 | else
57 | {
58 | count.i--;
59 | return RemoveResult.Removed;
60 | }
61 | }
62 |
63 | return RemoveResult.NotFound;
64 | }
65 |
66 | public RemoveResult RemoveAll(T item)
67 | {
68 | return set.Remove(item) ? RemoveResult.RemovedLast : RemoveResult.NotFound;
69 | }
70 |
71 | public bool Contains(T item)
72 | {
73 | return set.ContainsKey(item);
74 | }
75 |
76 | public enum AddResult : byte
77 | {
78 | AddedFirst,
79 | Added,
80 | AlreadyContained
81 | }
82 |
83 | public enum RemoveResult : byte
84 | {
85 | NotFound,
86 | RemovedLast,
87 | Removed
88 | }
89 |
90 | public void Clear()
91 | {
92 | set.Clear();
93 | }
94 |
95 | #region IEnumerable Members
96 |
97 | public IEnumerator GetEnumerator()
98 | {
99 | return set.Keys.GetEnumerator();
100 | }
101 |
102 | #endregion
103 |
104 | #region IEnumerable Members
105 |
106 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
107 | {
108 | return set.Keys.GetEnumerator();
109 | }
110 |
111 | #endregion
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/Windawesome/CurrentlyPlayingWidget.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 | using System.Windows.Forms;
4 |
5 | namespace Windawesome
6 | {
7 | public sealed class CurrentlyPlayingWidget : IFixedWidthWidget
8 | {
9 | private Bar bar;
10 |
11 | private Label label;
12 | private bool isLeft;
13 | private readonly string windowClassName;
14 | private readonly Color backgroundColor;
15 | private readonly Color foregroundColor;
16 |
17 | public CurrentlyPlayingWidget(string windowClassName = "{97E27FAA-C0B3-4b8e-A693-ED7881E99FC1}",
18 | Color? backgroundColor = null, Color? foregroundColor = null)
19 | {
20 | this.windowClassName = windowClassName;
21 |
22 | this.backgroundColor = backgroundColor ?? Color.White;
23 | this.foregroundColor = foregroundColor ?? Color.Black;
24 | }
25 |
26 | private void WindawesomeOnWindowTitleOrIconChanged(Workspace workspace, Window window, string newText, Bitmap newIcon)
27 | {
28 | if (window.className == windowClassName)
29 | {
30 | var oldLeft = label.Left;
31 | var oldRight = label.Right;
32 |
33 | var oldWidth = label.Width;
34 | var newWidth = TextRenderer.MeasureText(newText, label.Font).Width;
35 |
36 | label.Text = newText;
37 | label.Width = newWidth;
38 |
39 | if (oldWidth != newWidth)
40 | {
41 | this.RepositionControls(oldLeft, oldRight);
42 | bar.DoFixedWidthWidgetWidthChanged(this);
43 | }
44 | }
45 | }
46 |
47 | #region IWidget Members
48 |
49 | void IWidget.StaticInitializeWidget(Windawesome windawesome)
50 | {
51 | }
52 |
53 | void IWidget.InitializeWidget(Bar bar)
54 | {
55 | this.bar = bar;
56 |
57 | Windawesome.WindowTitleOrIconChanged += WindawesomeOnWindowTitleOrIconChanged;
58 |
59 | var hWnd = NativeMethods.FindWindow(windowClassName, null);
60 | var text = NativeMethods.GetText(hWnd);
61 | label = bar.CreateLabel(text, 0);
62 | label.BackColor = backgroundColor;
63 | label.ForeColor = foregroundColor;
64 | label.TextAlign = ContentAlignment.MiddleCenter;
65 | }
66 |
67 | IEnumerable IFixedWidthWidget.GetInitialControls(bool isLeft)
68 | {
69 | this.isLeft = isLeft;
70 |
71 | return new[] { label };
72 | }
73 |
74 | public void RepositionControls(int left, int right)
75 | {
76 | this.label.Location = this.isLeft ? new Point(left, 0) : new Point(right - this.label.Width, 0);
77 | }
78 |
79 | int IWidget.GetLeft()
80 | {
81 | return label.Left;
82 | }
83 |
84 | int IWidget.GetRight()
85 | {
86 | return label.Right;
87 | }
88 |
89 | void IWidget.StaticDispose()
90 | {
91 | }
92 |
93 | void IWidget.Dispose()
94 | {
95 | }
96 |
97 | void IWidget.Refresh()
98 | {
99 | }
100 |
101 | #endregion
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/Windawesome/RamMonitorWidget.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Drawing;
5 | using System.Windows.Forms;
6 |
7 | namespace Windawesome
8 | {
9 | public sealed class RamMonitorWidget : IFixedWidthWidget
10 | {
11 | private Bar bar;
12 |
13 | private Label label;
14 | private bool isLeft;
15 | private readonly PerformanceCounter counter;
16 | private readonly Timer updateTimer;
17 | private readonly string prefix;
18 | private readonly string postfix;
19 | private readonly Color backgroundColor;
20 | private readonly Color foregroundColor;
21 |
22 | public RamMonitorWidget(string prefix = "RAM:", string postfix = "%", int updateTime = 1000,
23 | Color? backgroundColor = null, Color? foregroundColor = null)
24 | {
25 | updateTimer = new Timer { Interval = updateTime };
26 | updateTimer.Tick += OnTimerTick;
27 |
28 | this.prefix = prefix;
29 | this.postfix = postfix;
30 |
31 | this.backgroundColor = backgroundColor ?? Color.White;
32 | this.foregroundColor = foregroundColor ?? Color.Black;
33 |
34 | counter = new PerformanceCounter("Memory", "% Committed Bytes In Use");
35 | }
36 |
37 | private void OnTimerTick(object sender, EventArgs e)
38 | {
39 | var oldLeft = label.Left;
40 | var oldRight = label.Right;
41 | var nextValue = counter.NextValue();
42 |
43 | label.Text = prefix + nextValue.ToString("00") + postfix;
44 |
45 | if (Math.Abs(nextValue - 100) < 0.00001)
46 | {
47 | this.RepositionControls(oldLeft, oldRight);
48 | bar.DoFixedWidthWidgetWidthChanged(this);
49 | }
50 | }
51 |
52 | #region IWidget Members
53 |
54 | void IWidget.StaticInitializeWidget(Windawesome windawesome)
55 | {
56 | }
57 |
58 | void IWidget.InitializeWidget(Bar bar)
59 | {
60 | this.bar = bar;
61 |
62 | label = bar.CreateLabel(prefix + counter.NextValue().ToString("00") + postfix, 0);
63 | label.BackColor = backgroundColor;
64 | label.ForeColor = foregroundColor;
65 | label.TextAlign = ContentAlignment.MiddleCenter;
66 |
67 | bar.BarShown += () => updateTimer.Start();
68 | bar.BarHidden += () => updateTimer.Stop();
69 | }
70 |
71 | IEnumerable IFixedWidthWidget.GetInitialControls(bool isLeft)
72 | {
73 | this.isLeft = isLeft;
74 |
75 | return new[] { label };
76 | }
77 |
78 | public void RepositionControls(int left, int right)
79 | {
80 | this.label.Location = this.isLeft ? new Point(left, 0) : new Point(right - this.label.Width, 0);
81 | }
82 |
83 | int IWidget.GetLeft()
84 | {
85 | return label.Left;
86 | }
87 |
88 | int IWidget.GetRight()
89 | {
90 | return label.Right;
91 | }
92 |
93 | void IWidget.StaticDispose()
94 | {
95 | }
96 |
97 | void IWidget.Dispose()
98 | {
99 | }
100 |
101 | void IWidget.Refresh()
102 | {
103 | }
104 |
105 | #endregion
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/Windawesome/CPUMonitorWidget.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Drawing;
5 | using System.Windows.Forms;
6 |
7 | namespace Windawesome
8 | {
9 | public sealed class CpuMonitorWidget : IFixedWidthWidget
10 | {
11 | private Bar bar;
12 |
13 | private Label label;
14 | private bool isLeft;
15 | private readonly PerformanceCounter counter;
16 | private readonly Timer updateTimer;
17 | private readonly string prefix;
18 | private readonly string postfix;
19 | private readonly Color backgroundColor;
20 | private readonly Color foregroundColor;
21 |
22 | public CpuMonitorWidget(string prefix = "CPU:", string postfix = "%", int updateTime = 1000,
23 | Color? backgroundColor = null, Color? foregroundColor = null)
24 | {
25 | updateTimer = new Timer { Interval = updateTime };
26 | updateTimer.Tick += OnTimerTick;
27 |
28 | this.prefix = prefix;
29 | this.postfix = postfix;
30 |
31 | this.backgroundColor = backgroundColor ?? Color.White;
32 | this.foregroundColor = foregroundColor ?? Color.Black;
33 |
34 | counter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
35 | }
36 |
37 | private void OnTimerTick(object sender, EventArgs e)
38 | {
39 | var oldLeft = label.Left;
40 | var oldRight = label.Right;
41 | var nextValue = counter.NextValue();
42 |
43 | label.Text = prefix + nextValue.ToString("00") + postfix;
44 |
45 | if (Math.Abs(nextValue - 100) < 0.00001)
46 | {
47 | this.RepositionControls(oldLeft, oldRight);
48 | bar.DoFixedWidthWidgetWidthChanged(this);
49 | }
50 | }
51 |
52 | #region IWidget Members
53 |
54 | void IWidget.StaticInitializeWidget(Windawesome windawesome)
55 | {
56 | }
57 |
58 | void IWidget.InitializeWidget(Bar bar)
59 | {
60 | this.bar = bar;
61 |
62 | label = bar.CreateLabel(prefix + counter.NextValue().ToString("00") + postfix, 0);
63 | label.BackColor = backgroundColor;
64 | label.ForeColor = foregroundColor;
65 | label.TextAlign = ContentAlignment.MiddleCenter;
66 |
67 | bar.BarShown += () => updateTimer.Start();
68 | bar.BarHidden += () => updateTimer.Stop();
69 | }
70 |
71 | IEnumerable IFixedWidthWidget.GetInitialControls(bool isLeft)
72 | {
73 | this.isLeft = isLeft;
74 |
75 | return new[] { label };
76 | }
77 |
78 | public void RepositionControls(int left, int right)
79 | {
80 | this.label.Location = this.isLeft ? new Point(left, 0) : new Point(right - this.label.Width, 0);
81 | }
82 |
83 | int IWidget.GetLeft()
84 | {
85 | return label.Left;
86 | }
87 |
88 | int IWidget.GetRight()
89 | {
90 | return label.Right;
91 | }
92 |
93 | void IWidget.StaticDispose()
94 | {
95 | }
96 |
97 | void IWidget.Dispose()
98 | {
99 | }
100 |
101 | void IWidget.Refresh()
102 | {
103 | }
104 |
105 | #endregion
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/Windawesome/LayoutWidget.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Windows.Forms;
5 |
6 | namespace Windawesome
7 | {
8 | public sealed class LayoutWidget : IFixedWidthWidget
9 | {
10 | private Label layoutLabel;
11 | private readonly Color backgroundColor;
12 | private readonly Color foregroundColor;
13 | private readonly Action onClick;
14 | private Bar bar;
15 | private bool isLeft;
16 |
17 | public LayoutWidget(Color? backgroundColor = null, Color? foregroundColor = null, Action onClick = null)
18 | {
19 | this.backgroundColor = backgroundColor ?? Color.FromArgb(0x99, 0xB4, 0xD1);
20 | this.foregroundColor = foregroundColor ?? Color.Black;
21 |
22 | this.onClick = onClick;
23 | }
24 |
25 | private void OnWorkspaceLayoutChanged(Workspace workspace)
26 | {
27 | if (workspace.Monitor == bar.Monitor && workspace.IsWorkspaceVisible)
28 | {
29 | var oldLeft = layoutLabel.Left;
30 | var oldRight = layoutLabel.Right;
31 | var oldWidth = layoutLabel.Width;
32 | layoutLabel.Text = workspace.Layout.LayoutSymbol();
33 | layoutLabel.Width = TextRenderer.MeasureText(layoutLabel.Text, layoutLabel.Font).Width;
34 | if (layoutLabel.Width != oldWidth)
35 | {
36 | this.RepositionControls(oldLeft, oldRight);
37 | bar.DoFixedWidthWidgetWidthChanged(this);
38 | }
39 | }
40 | }
41 |
42 | #region IWidget Members
43 |
44 | void IWidget.StaticInitializeWidget(Windawesome windawesome)
45 | {
46 | }
47 |
48 | void IWidget.InitializeWidget(Bar bar)
49 | {
50 | this.bar = bar;
51 |
52 | bar.BarShown += () => OnWorkspaceLayoutChanged(bar.Monitor.CurrentVisibleWorkspace);
53 |
54 | Workspace.LayoutUpdated += () => OnWorkspaceLayoutChanged(bar.Monitor.CurrentVisibleWorkspace);
55 | Workspace.WorkspaceShown += OnWorkspaceLayoutChanged;
56 | Workspace.WorkspaceLayoutChanged += (ws, _) => OnWorkspaceLayoutChanged(ws);
57 |
58 | layoutLabel = bar.CreateLabel("", 0);
59 | layoutLabel.TextAlign = ContentAlignment.MiddleCenter;
60 | layoutLabel.BackColor = backgroundColor;
61 | layoutLabel.ForeColor = foregroundColor;
62 | if (onClick != null)
63 | {
64 | layoutLabel.Click += (unused1, unused2) => onClick();
65 | }
66 | }
67 |
68 | IEnumerable IFixedWidthWidget.GetInitialControls(bool isLeft)
69 | {
70 | this.isLeft = isLeft;
71 |
72 | return new Control[] { layoutLabel };
73 | }
74 |
75 | public void RepositionControls(int left, int right)
76 | {
77 | this.layoutLabel.Location = this.isLeft ? new Point(left, 0) : new Point(right - this.layoutLabel.Width, 0);
78 | }
79 |
80 | int IWidget.GetLeft()
81 | {
82 | return layoutLabel.Left;
83 | }
84 |
85 | int IWidget.GetRight()
86 | {
87 | return layoutLabel.Right;
88 | }
89 |
90 | void IWidget.StaticDispose()
91 | {
92 | }
93 |
94 | void IWidget.Dispose()
95 | {
96 | }
97 |
98 | void IWidget.Refresh()
99 | {
100 | }
101 |
102 | #endregion
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/Windawesome/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.1
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Windawesome.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Windawesome.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | internal static System.Drawing.Bitmap Icon_missing {
64 | get {
65 | object obj = ResourceManager.GetObject("Icon_missing", resourceCulture);
66 | return ((System.Drawing.Bitmap)(obj));
67 | }
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/WindowSubclassing/WindowSubclassing.c:
--------------------------------------------------------------------------------
1 |
2 | #include "stdafx.h"
3 | #include "WindowSubclassing.h"
4 |
5 | #pragma data_seg(".shared")
6 | #pragma comment(linker, "/SECTION:.shared,RWS")
7 |
8 | HWND applicationHandle = NULL;
9 |
10 | UINT START_WINDOW_PROC_MESSAGE = 0;
11 | UINT STOP_WINDOW_PROC_MESSAGE = 0;
12 |
13 | #pragma data_seg()
14 |
15 | HINSTANCE hInstance;
16 | static WNDPROC oldWndProc = NULL;
17 | static BOOL isListening;
18 |
19 | static LRESULT CALLBACK CallWndRetProc(int code, WPARAM wParam, LPARAM lParam);
20 | static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
21 |
22 | BOOL SubclassWindow(HWND hWnd, HWND window)
23 | {
24 | HHOOK hook = SetWindowsHookEx(WH_CALLWNDPROCRET, (HOOKPROC) CallWndRetProc, hInstance, GetWindowThreadProcessId(window, NULL));
25 | if (!hook)
26 | {
27 | return FALSE;
28 | }
29 | applicationHandle = hWnd;
30 | SendMessage(window, START_WINDOW_PROC_MESSAGE, 0, 0);
31 | UnhookWindowsHookEx(hook);
32 | return TRUE;
33 | }
34 |
35 | BOOL UnsubclassWindow(HWND window)
36 | {
37 | HHOOK hook = SetWindowsHookEx(WH_CALLWNDPROCRET, (HOOKPROC) CallWndRetProc, hInstance, GetWindowThreadProcessId(window, NULL));
38 | if (!hook)
39 | {
40 | return FALSE;
41 | }
42 | SendMessage(window, STOP_WINDOW_PROC_MESSAGE, 0, 0);
43 | UnhookWindowsHookEx(hook);
44 | return TRUE;
45 | }
46 |
47 | static LRESULT CALLBACK CallWndRetProc(int code, WPARAM wParam, LPARAM lParam)
48 | {
49 | if (code >= 0)
50 | {
51 | if (((CWPRETSTRUCT*) lParam)->message == START_WINDOW_PROC_MESSAGE)
52 | {
53 | WCHAR library[MAX_PATH];
54 | GetModuleFileName(hInstance, library, MAX_PATH);
55 | LoadLibrary(library);
56 |
57 | isListening = FALSE; // because on the current workspace the window may need to be movable/resizable
58 | oldWndProc = (WNDPROC) SetWindowLongPtr(((CWPRETSTRUCT*) lParam)->hwnd, GWLP_WNDPROC, (LONG_PTR) WindowProc);
59 | if (!oldWndProc)
60 | {
61 | FreeLibrary(hInstance);
62 | }
63 | return TRUE;
64 | }
65 | if (((CWPRETSTRUCT*) lParam)->message == STOP_WINDOW_PROC_MESSAGE)
66 | {
67 | if (oldWndProc && SetWindowLongPtr(((CWPRETSTRUCT*) lParam)->hwnd, GWLP_WNDPROC, (LONG_PTR) oldWndProc))
68 | {
69 | FreeLibrary(hInstance);
70 | oldWndProc = NULL;
71 | }
72 | return TRUE;
73 | }
74 | }
75 |
76 | return CallNextHookEx(NULL, code, wParam, lParam);
77 | }
78 |
79 | static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
80 | {
81 | if (msg == START_WINDOW_PROC_MESSAGE)
82 | {
83 | isListening = TRUE;
84 | return TRUE;
85 | }
86 | if (isListening)
87 | {
88 | if (msg == STOP_WINDOW_PROC_MESSAGE)
89 | {
90 | isListening = FALSE;
91 | return TRUE;
92 | }
93 | switch (msg)
94 | {
95 | case WM_MOVING:
96 | case WM_SIZING:
97 | GetWindowRect(hwnd, (RECT*) lParam);
98 | return TRUE;
99 | case WM_NCLBUTTONDBLCLK:
100 | if (wParam == HTCAPTION)
101 | {
102 | return 0;
103 | }
104 | break;
105 | case WM_SYSCOMMAND:
106 | if (wParam == 0xF012 || wParam == SC_RESTORE || wParam == SC_MOVE || wParam == SC_SIZE)
107 | {
108 | return 0;
109 | }
110 | }
111 | }
112 |
113 | return CallWindowProc(oldWndProc, hwnd, msg, wParam, lParam);
114 | }
115 |
--------------------------------------------------------------------------------
/Windawesome/NetworkMonitorWidget.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Net.NetworkInformation;
4 | using System.Drawing;
5 | using System.Windows.Forms;
6 |
7 | namespace Windawesome
8 | {
9 | public sealed class NetworkMonitorWidget : IFixedWidthWidget
10 | {
11 | private Bar bar;
12 |
13 | private Label label;
14 | private bool isLeft;
15 | private readonly Timer updateTimer;
16 | private readonly Color backgroundColor;
17 | private readonly Color foregroundColor;
18 | private long oldReceived;
19 | private long oldSent;
20 | private NetworkInterface networkInterface;
21 | private int updateDuration;
22 |
23 | public NetworkMonitorWidget(int interfaceId = 0, int updateTime = 1000,
24 | Color? backgroundColor = null, Color? foregroundColor = null)
25 | {
26 | this.backgroundColor = backgroundColor ?? Color.White;
27 | this.foregroundColor = foregroundColor ?? Color.Black;
28 |
29 | if (!NetworkInterface.GetIsNetworkAvailable())
30 | {
31 | return;
32 | }
33 |
34 | updateDuration = updateTime;
35 | updateTimer = new Timer { Interval = updateTime };
36 | updateTimer.Tick += OnTimerTick;
37 |
38 | networkInterface = NetworkInterface.GetAllNetworkInterfaces()[interfaceId];
39 | oldReceived = networkInterface.GetIPv4Statistics().BytesReceived;
40 | oldSent = networkInterface.GetIPv4Statistics().BytesSent;
41 | }
42 |
43 | private void OnTimerTick(object sender, EventArgs e)
44 | {
45 | var oldLeft = label.Left;
46 | var oldRight = label.Right;
47 |
48 | var curReceived = networkInterface.GetIPv4Statistics().BytesReceived;
49 | var downSpeed = ((float) (curReceived - oldReceived)) / updateDuration * 1000 / 1024;
50 | var curSent = networkInterface.GetIPv4Statistics().BytesSent;
51 | var upSpeed = ((float) (curSent - oldSent)) / updateDuration * 1000 / 1024;
52 |
53 | var oldWidth = label.Width;
54 | label.Text = string.Format("\u2193{0}{1} \u2191{2}{3}", ((downSpeed > 999) ? downSpeed / 1024 : downSpeed).ToString("0.0"),
55 | ((downSpeed > 999) ? "M" : "k"), ((upSpeed > 999) ? upSpeed / 1024 : upSpeed).ToString("0.0"), ((upSpeed > 999) ? "M" : "k"));
56 | var newWidth = TextRenderer.MeasureText(label.Text, label.Font).Width;
57 | label.Width = newWidth;
58 |
59 | if (oldWidth != newWidth)
60 | {
61 | this.RepositionControls(oldLeft, oldRight);
62 | bar.DoFixedWidthWidgetWidthChanged(this);
63 | }
64 |
65 | oldSent = curSent;
66 | oldReceived = curReceived;
67 | }
68 |
69 | #region IWidget Members
70 |
71 | void IWidget.StaticInitializeWidget(Windawesome windawesome)
72 | {
73 | }
74 |
75 | void IWidget.InitializeWidget(Bar bar)
76 | {
77 | this.bar = bar;
78 |
79 | label = bar.CreateLabel("", 0);
80 | label.BackColor = backgroundColor;
81 | label.ForeColor = foregroundColor;
82 | label.TextAlign = ContentAlignment.MiddleCenter;
83 |
84 | bar.BarShown += () => updateTimer.Start();
85 | bar.BarHidden += () => updateTimer.Stop();
86 | }
87 |
88 | IEnumerable IFixedWidthWidget.GetInitialControls(bool isLeft)
89 | {
90 | this.isLeft = isLeft;
91 |
92 | return new[] { label };
93 | }
94 |
95 | public void RepositionControls(int left, int right)
96 | {
97 | this.label.Location = this.isLeft ? new Point(left, 0) : new Point(right - this.label.Width, 0);
98 | }
99 |
100 | int IWidget.GetLeft()
101 | {
102 | return label.Left;
103 | }
104 |
105 | int IWidget.GetRight()
106 | {
107 | return label.Right;
108 | }
109 |
110 | void IWidget.StaticDispose()
111 | {
112 | }
113 |
114 | void IWidget.Dispose()
115 | {
116 | }
117 |
118 | void IWidget.Refresh()
119 | {
120 | }
121 |
122 | #endregion
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/Windawesome/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Linq;
4 | using System.Runtime.CompilerServices;
5 | using System.Threading;
6 | using System.Windows.Forms;
7 |
8 | [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
9 |
10 | namespace Windawesome
11 | {
12 | static class Program
13 | {
14 | private static Windawesome windawesome;
15 |
16 | [STAThread]
17 | static void Main()
18 | {
19 | bool createdNew;
20 | using (new Mutex(true, "{BCDA45B7-407E-43F3-82FB-D1F6D6D093FF}", out createdNew))
21 | {
22 | if (createdNew) // if the mutex was taken successfully, i.e. this is the first instance of the app running
23 | {
24 | SetPriorities();
25 |
26 | Application.EnableVisualStyles();
27 | Application.SetCompatibleTextRenderingDefault(false);
28 |
29 | // set exception handling
30 | Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
31 | Application.ThreadException += OnApplicationThreadException;
32 | AppDomain.CurrentDomain.UnhandledException += (_, e) => OnException(e.ExceptionObject as Exception);
33 |
34 | windawesome = new Windawesome();
35 | Application.Run(new WindawesomeApplicationContext());
36 |
37 | Application.ThreadException -= OnApplicationThreadException;
38 | }
39 | }
40 | }
41 |
42 | private static void SetPriorities()
43 | {
44 | Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
45 | Thread.CurrentThread.Priority = ThreadPriority.Highest;
46 |
47 | if (SystemAndProcessInformation.isAtLeastVista)
48 | {
49 | var currentProcessHandle = NativeMethods.GetCurrentProcess();
50 |
51 | var defaultMemoryPriority = NativeMethods.DefaultMemoryPriority;
52 | NativeMethods.NtSetInformationProcess(currentProcessHandle, NativeMethods.ProcessInformationMemoryPriority,
53 | ref defaultMemoryPriority, sizeof (uint));
54 |
55 | var defaultIOPriority = NativeMethods.DefaultIOPriority;
56 | NativeMethods.NtSetInformationProcess(currentProcessHandle, NativeMethods.ProcessInformationIOPriority,
57 | ref defaultIOPriority, sizeof (uint));
58 | }
59 | }
60 |
61 | private static void OnApplicationThreadException(object sender, ThreadExceptionEventArgs e)
62 | {
63 | OnException(e.Exception);
64 | }
65 |
66 | private static void OnException(Exception e)
67 | {
68 | System.IO.File.AppendAllLines("log.txt", new[]
69 | {
70 | "------------------------------------",
71 | DateTime.Now.ToString(),
72 | "Assemblies:",
73 | System.Reflection.Assembly.GetExecutingAssembly().FullName
74 | }.
75 | Concat(System.Reflection.Assembly.GetExecutingAssembly().GetReferencedAssemblies().Select(a => a.FullName)).
76 | Concat(new[]
77 | {
78 | "",
79 | "OS: " + Environment.OSVersion.VersionString,
80 | "CLR: " + Environment.Version.ToString(3),
81 | "64-bit OS: " + Environment.Is64BitOperatingSystem,
82 | "64-bit process: " + Environment.Is64BitProcess,
83 | "Elevated: " + SystemAndProcessInformation.isRunningElevated,
84 | e.ToString(),
85 | "Inner Exception:",
86 | e.InnerException != null ? e.InnerException.ToString() : "none"
87 | }));
88 |
89 | if (windawesome != null)
90 | {
91 | MessageBox.Show("An exception has occurred. Windawesome will now close. " +
92 | "Please see the log file in the program directory and post an issue on the website " +
93 | "if you think this is a bug.",
94 | "Exception occurred");
95 | windawesome.Quit();
96 | }
97 | }
98 |
99 | private class WindawesomeApplicationContext : ApplicationContext
100 | {
101 | public WindawesomeApplicationContext()
102 | {
103 | Windawesome.WindawesomeExiting += this.ExitThread;
104 | }
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/Windawesome/LaptopBatteryMonitorWidget.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 | using System.Windows.Forms;
4 |
5 | namespace Windawesome
6 | {
7 | public sealed class LaptopBatteryMonitorWidget : IFixedWidthWidget
8 | {
9 | private Bar bar;
10 |
11 | private Label label;
12 | private bool isLeft;
13 | private readonly Timer updateTimer;
14 | private readonly string textForCharging;
15 | private readonly string textForNotCharging;
16 | private readonly string prefix;
17 | private readonly string postfix;
18 | private readonly Color backgroundColor;
19 | private readonly Color foregroundColor;
20 |
21 | public LaptopBatteryMonitorWidget(string textForCharging = "C", string textForNotCharging = "B",
22 | string prefix = " ", string postfix = "%", int updateTime = 60000,
23 | Color? backgroundColor = null, Color? foregroundColor = null)
24 | {
25 | updateTimer = new Timer { Interval = updateTime };
26 | updateTimer.Tick += OnTimerTick;
27 |
28 | this.textForCharging = textForCharging;
29 | this.textForNotCharging = textForNotCharging;
30 |
31 | this.prefix = prefix;
32 | this.postfix = postfix;
33 |
34 | this.backgroundColor = backgroundColor ?? Color.White;
35 | this.foregroundColor = foregroundColor ?? Color.Black;
36 | }
37 |
38 | private void OnTimerTick(object sender, System.EventArgs e)
39 | {
40 | var powerStatus = SystemInformation.PowerStatus;
41 | switch (powerStatus.BatteryChargeStatus)
42 | {
43 | case BatteryChargeStatus.Critical:
44 | label.ForeColor = Color.Red;
45 | break;
46 | case BatteryChargeStatus.High:
47 | label.ForeColor = Color.Green;
48 | break;
49 | case BatteryChargeStatus.Low:
50 | label.ForeColor = Color.Orange;
51 | break;
52 | }
53 |
54 | var oldLeft = label.Left;
55 | var oldRight = label.Right;
56 | var oldWidth = label.Width;
57 | label.Text = (powerStatus.PowerLineStatus == PowerLineStatus.Offline ?
58 | textForNotCharging : textForCharging) + prefix + (powerStatus.BatteryLifePercent * 100) + postfix;
59 |
60 | label.Width = TextRenderer.MeasureText(label.Text, label.Font).Width;
61 | if (oldWidth != label.Width)
62 | {
63 | this.RepositionControls(oldLeft, oldRight);
64 | bar.DoFixedWidthWidgetWidthChanged(this);
65 | }
66 | }
67 |
68 | void IWidget.StaticInitializeWidget(Windawesome windawesome)
69 | {
70 | }
71 |
72 | void IWidget.InitializeWidget(Bar bar)
73 | {
74 | this.bar = bar;
75 |
76 | var powerStatus = SystemInformation.PowerStatus;
77 | label = bar.CreateLabel((powerStatus.PowerLineStatus == PowerLineStatus.Offline ?
78 | textForNotCharging : textForCharging) + prefix + (powerStatus.BatteryLifePercent * 100) + postfix, 0);
79 | label.BackColor = backgroundColor;
80 | label.ForeColor = foregroundColor;
81 | label.TextAlign = ContentAlignment.MiddleCenter;
82 | switch (powerStatus.BatteryChargeStatus)
83 | {
84 | case BatteryChargeStatus.Critical:
85 | label.ForeColor = Color.Red;
86 | break;
87 | case BatteryChargeStatus.High:
88 | label.ForeColor = Color.Green;
89 | break;
90 | case BatteryChargeStatus.Low:
91 | label.ForeColor = Color.Orange;
92 | break;
93 | case BatteryChargeStatus.NoSystemBattery:
94 | label.ForeColor = Color.Black;
95 | label.Text = @"NO BAT";
96 | return ;
97 | }
98 |
99 | bar.BarShown += () => updateTimer.Start();
100 | bar.BarHidden += () => updateTimer.Stop();
101 | }
102 |
103 | IEnumerable IFixedWidthWidget.GetInitialControls(bool isLeft)
104 | {
105 | this.isLeft = isLeft;
106 |
107 | return new[] { label };
108 | }
109 |
110 | public void RepositionControls(int left, int right)
111 | {
112 | this.label.Location = this.isLeft ? new Point(left, 0) : new Point(right - this.label.Width, 0);
113 | }
114 |
115 | int IWidget.GetLeft()
116 | {
117 | return label.Left;
118 | }
119 |
120 | int IWidget.GetRight()
121 | {
122 | return label.Right;
123 | }
124 |
125 | void IWidget.StaticDispose()
126 | {
127 | }
128 |
129 | void IWidget.Dispose()
130 | {
131 | }
132 |
133 | void IWidget.Refresh()
134 | {
135 | }
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/Windawesome/FullScreenLayout.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Windawesome
3 | {
4 | public sealed class FullScreenLayout : ILayout
5 | {
6 | private Workspace workspace;
7 |
8 | private void MaximizeWindow(Window window)
9 | {
10 | if (Utilities.WindowIsNotHung(window))
11 | {
12 | var newMonitorBounds = workspace.Monitor.Bounds;
13 | var newMonitorWorkingArea = workspace.Monitor.WorkingArea;
14 |
15 | var hWindowsMonitor = NativeMethods.MonitorFromWindow(window.hWnd, NativeMethods.MFRF.MONITOR_MONITOR_DEFAULTTONULL);
16 | var windowsMonitorInfo = NativeMethods.MONITORINFO.Default;
17 | NativeMethods.GetMonitorInfo(hWindowsMonitor, ref windowsMonitorInfo);
18 | var windowsMonitorBounds = windowsMonitorInfo.rcMonitor.ToRectangle();
19 |
20 | var winPlacement = NativeMethods.WINDOWPLACEMENT.Default;
21 | NativeMethods.GetWindowPlacement(window.hWnd, ref winPlacement);
22 |
23 | winPlacement.MaxPosition.X = newMonitorBounds.Left;
24 | winPlacement.MaxPosition.Y = newMonitorBounds.Top;
25 |
26 | if (NativeMethods.IsZoomed(window.hWnd) && windowsMonitorBounds != newMonitorBounds)
27 | {
28 | // restore if program is maximized and should be on a different monitor
29 | NativeMethods.ShowWindow(window.hWnd, NativeMethods.SW.SW_SHOWNOACTIVATE); // should not use SW_RESTORE as it activates the window
30 | System.Threading.Thread.Sleep(NativeMethods.minimizeRestoreDelay);
31 | }
32 |
33 | var ws = NativeMethods.GetWindowStyleLongPtr(window.hWnd);
34 | if (ws.HasFlag(NativeMethods.WS.WS_CAPTION | NativeMethods.WS.WS_MAXIMIZEBOX))
35 | {
36 | if (windowsMonitorBounds != newMonitorBounds)
37 | {
38 | winPlacement.NormalPosition.left += newMonitorBounds.Left - windowsMonitorBounds.Left; // these are in working area coordinates
39 | winPlacement.NormalPosition.right += newMonitorBounds.Right - windowsMonitorBounds.Right;
40 | winPlacement.NormalPosition.top += newMonitorBounds.Top - windowsMonitorBounds.Top;
41 | winPlacement.NormalPosition.bottom += newMonitorBounds.Bottom - windowsMonitorBounds.Bottom;
42 | }
43 |
44 | winPlacement.ShowCmd = NativeMethods.SW.SW_SHOWMAXIMIZED;
45 | }
46 | else
47 | {
48 | winPlacement.NormalPosition.left = newMonitorBounds.Left; // these are in working area coordinates
49 | winPlacement.NormalPosition.right = newMonitorBounds.Left + newMonitorWorkingArea.Width;
50 | winPlacement.NormalPosition.top = newMonitorBounds.Top;
51 | winPlacement.NormalPosition.bottom = newMonitorBounds.Top + newMonitorWorkingArea.Height;
52 |
53 | winPlacement.ShowCmd = NativeMethods.SW.SW_SHOWNOACTIVATE;
54 | }
55 |
56 | NativeMethods.SetWindowPlacement(window.hWnd, ref winPlacement);
57 | }
58 | }
59 |
60 | private void OnWorkspaceWindowAddedOrRemoved(Workspace workspace, Window window)
61 | {
62 | if (workspace == this.workspace && workspace.IsWorkspaceVisible)
63 | {
64 | Workspace.DoLayoutUpdated();
65 | }
66 | }
67 |
68 | #region ILayout Members
69 |
70 | string ILayout.LayoutSymbol()
71 | {
72 | return workspace.GetWindowsCount() == 0 ? "[M]" : "[" + workspace.GetWindowsCount() + "]";
73 | }
74 |
75 | public string LayoutName()
76 | {
77 | return "Full Screen";
78 | }
79 |
80 | void ILayout.Initialize(Workspace workspace)
81 | {
82 | this.workspace = workspace;
83 |
84 | workspace.WindowTitlebarToggled += MaximizeWindow;
85 | workspace.WindowBorderToggled += MaximizeWindow;
86 |
87 | Workspace.WorkspaceWindowAdded += OnWorkspaceWindowAddedOrRemoved;
88 | Workspace.WorkspaceWindowRemoved += OnWorkspaceWindowAddedOrRemoved;
89 | }
90 |
91 | void ILayout.Dispose()
92 | {
93 | workspace.WindowTitlebarToggled -= MaximizeWindow;
94 | workspace.WindowBorderToggled -= MaximizeWindow;
95 |
96 | Workspace.WorkspaceWindowAdded -= OnWorkspaceWindowAddedOrRemoved;
97 | Workspace.WorkspaceWindowRemoved -= OnWorkspaceWindowAddedOrRemoved;
98 | }
99 |
100 | bool ILayout.ShouldSaveAndRestoreSharedWindowsPosition()
101 | {
102 | return false;
103 | }
104 |
105 | void ILayout.Reposition()
106 | {
107 | workspace.GetLayoutManagedWindows().ForEach(MaximizeWindow);
108 | Workspace.DoLayoutUpdated();
109 | }
110 |
111 | void ILayout.WindowMinimized(Window window)
112 | {
113 | }
114 |
115 | void ILayout.WindowRestored(Window window)
116 | {
117 | (this as ILayout).WindowCreated(window);
118 | }
119 |
120 | void ILayout.WindowCreated(Window window)
121 | {
122 | if (workspace.IsWorkspaceVisible)
123 | {
124 | MaximizeWindow(window);
125 | }
126 | }
127 |
128 | void ILayout.WindowDestroyed(Window window)
129 | {
130 | }
131 |
132 | #endregion
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/Config/2-Program Rules.py:
--------------------------------------------------------------------------------
1 | from Windawesome import Windawesome, ProgramRule, State, OnWindowCreatedOrShownAction, OnWindowCreatedOnWorkspaceAction
2 | from Windawesome.NativeMethods import WS, WS_EX
3 |
4 | config.ProgramRules = [
5 | ProgramRule(
6 | className = "^cygwin/x X rl$",
7 | windowCreatedDelay = 300,
8 | rules = [ProgramRule.Rule(workspace = 5)]
9 | ),
10 | ProgramRule(
11 | className = "^TApplication$",
12 | displayName = "^Find and Run Robot$",
13 | isManaged = False
14 | ),
15 | ProgramRule(
16 | className = "^TApplication$",
17 | rules = [ProgramRule.Rule(isFloating = True)]
18 | ),
19 | ProgramRule(
20 | className = "^MozillaWindowClass$",
21 | rules = [ProgramRule.Rule(workspace = 2)]
22 | ),
23 | ProgramRule(
24 | className = "^MozillaDialogClass$",
25 | rules = [ProgramRule.Rule(workspace = 2, isFloating = True)]
26 | ),
27 | ProgramRule(
28 | className = "^CabinetWClass$", # Windows Explorer
29 | updateIcon = True,
30 | rules = [ProgramRule.Rule(workspace = 1)]
31 | ),
32 | ProgramRule(
33 | className = "^ExploreWClass$", # Windows Explorer
34 | updateIcon = True,
35 | rules = [ProgramRule.Rule(workspace = 1)]
36 | ),
37 | ProgramRule(
38 | className = "^wxWindowNR$",
39 | displayName = ".*BitComet.*",
40 | onWindowCreatedAction = OnWindowCreatedOrShownAction.HideWindow,
41 | onHiddenWindowShownAction = OnWindowCreatedOrShownAction.HideWindow,
42 | showMenu = False,
43 | rules = [ProgramRule.Rule(workspace = 9, titlebar = State.HIDDEN, windowBorders = State.HIDDEN)]
44 | ),
45 | ProgramRule(
46 | displayName = ".*SA Dictionary 2010.*",
47 | rules = [ProgramRule.Rule(isFloating = True)]
48 | ),
49 | ProgramRule(
50 | className = "^rctrl_renwnd32$", # Outlook
51 | rules = [ProgramRule.Rule(workspace = 8)]
52 | ),
53 | ProgramRule(
54 | className = "^{97E27FAA-C0B3-4b8e-A693-ED7881E99FC1}$", # foobar2000
55 | rules = [ProgramRule.Rule(workspace = 7)]
56 | ),
57 |
58 | # editors
59 |
60 | ProgramRule(
61 | className = "^Vim$",
62 | windowCreatedDelay = 100,
63 | rules = [ProgramRule.Rule(workspace = 3, titlebar = State.HIDDEN, windowBorders = State.HIDDEN)]
64 | ),
65 | ProgramRule(
66 | className = "^XLMAIN$", # Excel
67 | rules = [ProgramRule.Rule(redrawOnShow = True)]
68 | ),
69 | ProgramRule(
70 | displayName = ".*Microsoft Visual Studio.*",
71 | onWindowCreatedAction = OnWindowCreatedOrShownAction.HideWindow,
72 | rules = [ProgramRule.Rule(workspace = 5, titlebar = State.HIDDEN, windowBorders = State.HIDDEN)]
73 | ),
74 |
75 | # media players
76 |
77 | ProgramRule(
78 | className = "^MediaPlayerClassicW$",
79 | rules = [ProgramRule.Rule(workspace = 1)]
80 | ),
81 |
82 | # chat
83 |
84 | ProgramRule(
85 | className = "^icoTrilly$",
86 | onWindowCreatedAction = OnWindowCreatedOrShownAction.TemporarilyShowWindowOnCurrentWorkspace,
87 | onWindowCreatedOnInactiveWorkspaceAction = OnWindowCreatedOnWorkspaceAction.PreserveTopmostWindow,
88 | rules = [ProgramRule.Rule(workspace = 4, isFloating = True)]
89 | ),
90 | ProgramRule(
91 | className = "^ico.*",
92 | processName = "^trillian$",
93 | onWindowCreatedAction = OnWindowCreatedOrShownAction.HideWindow,
94 | onWindowCreatedOnCurrentWorkspaceAction = OnWindowCreatedOnWorkspaceAction.PreserveTopmostWindow,
95 | onWindowCreatedOnInactiveWorkspaceAction = OnWindowCreatedOnWorkspaceAction.PreserveTopmostWindow,
96 | rules = [ProgramRule.Rule(workspace = 4)]
97 | ),
98 |
99 | # terminals
100 |
101 | ProgramRule(
102 | className = "^Console_2_Main$",
103 | rules = [ProgramRule.Rule(workspace = 3)]
104 | ),
105 | ProgramRule(
106 | className = "^mintty$",
107 | redrawDesktopOnWindowCreated = True,
108 | rules = [ProgramRule.Rule(workspace = 3, titlebar = State.HIDDEN, windowBorders = State.HIDDEN)]
109 | ),
110 |
111 | # other
112 |
113 | ProgramRule(
114 | displayName = "^Windows 7 Manager - Junk File Cleaner$",
115 | isManaged = False
116 | ),
117 | ProgramRule(
118 | displayName = "^Windows 7 Manager - Registry Cleaner$",
119 | isManaged = False
120 | ),
121 | ProgramRule(
122 | displayName = ".*Windows 7 Manager.*",
123 | rules = [ProgramRule.Rule(workspace = 1)]
124 | ),
125 | ProgramRule(
126 | className = "^MsiDialogCloseClass$",
127 | isManaged = False
128 | ),
129 | ProgramRule(
130 | className = "^MsiDialogNoCloseClass$",
131 | isManaged = False
132 | ),
133 | ProgramRule(
134 | className = "^\$\$\$Secure UAP Dummy Window Class For Interim Dialog$"
135 | ),
136 | ProgramRule(
137 | className = "^#32770$", # all dialogs
138 | rules = [ProgramRule.Rule(isFloating = True)] # should be floating
139 | ),
140 | ProgramRule(
141 | styleContains = WS.WS_POPUP,
142 | isManaged = False
143 | ),
144 | ProgramRule(
145 | styleNotContains = WS.WS_MAXIMIZEBOX,
146 | rules = [ProgramRule.Rule(isFloating = True)]
147 | ),
148 | ProgramRule() # an all-catching rule in the end to manage all other windows
149 | ]
150 |
--------------------------------------------------------------------------------
/Windawesome/LanguageBarWidget.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Text;
5 | using System.Windows.Forms;
6 |
7 | namespace Windawesome
8 | {
9 | public sealed class LanguageBarWidget : IFixedWidthWidget
10 | {
11 | private uint globalShellHookMessage;
12 | private Bar bar;
13 |
14 | private Label label;
15 | private bool isLeft;
16 | private readonly Color backgroundColor;
17 | private readonly Color foregroundColor;
18 | private readonly static StringBuilder stringBuilder = new StringBuilder(85);
19 |
20 | private delegate void InputLanguageChangedEventHandler(IntPtr hWnd);
21 | private static event InputLanguageChangedEventHandler InputLanguageChanged;
22 |
23 | public LanguageBarWidget(Color? backgroundColor = null, Color? foregroundColor = null)
24 | {
25 | this.backgroundColor = backgroundColor ?? Color.White;
26 | this.foregroundColor = foregroundColor ?? Color.Black;
27 | }
28 |
29 | private static bool OnGlobalShellHookMessage(ref Message m)
30 | {
31 | InputLanguageChanged(NativeMethods.GetForegroundWindow());
32 | return true;
33 | }
34 |
35 | private static string GetWindowKeyboardLanguage(IntPtr hWnd)
36 | {
37 | var keyboardLayout = NativeMethods.GetKeyboardLayout(
38 | NativeMethods.GetWindowThreadProcessId(hWnd, IntPtr.Zero));
39 |
40 | var localeId = unchecked((uint) (short) keyboardLayout.ToInt32());
41 |
42 | if (SystemAndProcessInformation.isAtLeastVista)
43 | {
44 | NativeMethods.LCIDToLocaleName(localeId, stringBuilder, stringBuilder.Capacity, 0);
45 | return stringBuilder.ToString();
46 | }
47 |
48 | // XP doesn't have LCIDToLocaleName
49 | NativeMethods.GetLocaleInfo(localeId, NativeMethods.LOCALE_SISO639LANGNAME, stringBuilder, stringBuilder.Capacity);
50 | var languageName = stringBuilder.ToString();
51 | NativeMethods.GetLocaleInfo(localeId, NativeMethods.LOCALE_SISO3166CTRYNAME, stringBuilder, stringBuilder.Capacity);
52 | return languageName + "-" + stringBuilder;
53 | }
54 |
55 | private void SetNewLanguage(string language)
56 | {
57 | if (language != label.Text)
58 | {
59 | var oldLeft = label.Left;
60 | var oldRight = label.Right;
61 | var oldWidth = label.Width;
62 | label.Text = language;
63 |
64 | label.Width = TextRenderer.MeasureText(label.Text, label.Font).Width;
65 | if (oldWidth != label.Width)
66 | {
67 | this.RepositionControls(oldLeft, oldRight);
68 | bar.DoFixedWidthWidgetWidthChanged(this);
69 | }
70 | }
71 | }
72 |
73 | private void SetNewLanguage(IntPtr hWnd)
74 | {
75 | if (bar.Monitor.CurrentVisibleWorkspace.IsCurrentWorkspace)
76 | {
77 | SetNewLanguage(GetWindowKeyboardLanguage(hWnd));
78 | }
79 | }
80 |
81 | #region IFixedWidthWidget Members
82 |
83 | void IWidget.StaticInitializeWidget(Windawesome windawesome)
84 | {
85 | if (NativeMethods.RegisterGlobalShellHook(windawesome.Handle))
86 | {
87 | globalShellHookMessage = NativeMethods.RegisterWindowMessage("GLOBAL_SHELL_HOOK");
88 | if (SystemAndProcessInformation.isAtLeastVista && SystemAndProcessInformation.isRunningElevated)
89 | {
90 | if (SystemAndProcessInformation.isAtLeast7)
91 | {
92 | NativeMethods.ChangeWindowMessageFilterEx(windawesome.Handle, globalShellHookMessage, NativeMethods.MSGFLTEx.MSGFLT_ALLOW, IntPtr.Zero);
93 | }
94 | else
95 | {
96 | NativeMethods.ChangeWindowMessageFilter(globalShellHookMessage, NativeMethods.MSGFLT.MSGFLT_ADD);
97 | }
98 | }
99 |
100 | windawesome.RegisterMessage((int) globalShellHookMessage, OnGlobalShellHookMessage);
101 | }
102 | }
103 |
104 | void IWidget.InitializeWidget(Bar bar)
105 | {
106 | this.bar = bar;
107 |
108 | label = bar.CreateLabel("", 0);
109 | label.BackColor = backgroundColor;
110 | label.ForeColor = foregroundColor;
111 | label.TextAlign = ContentAlignment.MiddleCenter;
112 |
113 | Workspace.WindowActivatedEvent += SetNewLanguage;
114 | InputLanguageChanged += SetNewLanguage;
115 | }
116 |
117 | IEnumerable IFixedWidthWidget.GetInitialControls(bool isLeft)
118 | {
119 | this.isLeft = isLeft;
120 |
121 | return new[] { label };
122 | }
123 |
124 | public void RepositionControls(int left, int right)
125 | {
126 | this.label.Location = this.isLeft ? new Point(left, 0) : new Point(right - this.label.Width, 0);
127 | }
128 |
129 | int IWidget.GetLeft()
130 | {
131 | return label.Left;
132 | }
133 |
134 | int IWidget.GetRight()
135 | {
136 | return label.Right;
137 | }
138 |
139 | void IWidget.StaticDispose()
140 | {
141 | NativeMethods.UnregisterGlobalShellHook();
142 |
143 | // remove the message filters
144 | if (SystemAndProcessInformation.isAtLeastVista && SystemAndProcessInformation.isRunningElevated)
145 | {
146 | if (SystemAndProcessInformation.isAtLeast7)
147 | {
148 | NativeMethods.ChangeWindowMessageFilterEx(Windawesome.HandleStatic, globalShellHookMessage, NativeMethods.MSGFLTEx.MSGFLT_RESET, IntPtr.Zero);
149 | }
150 | else
151 | {
152 | NativeMethods.ChangeWindowMessageFilter(globalShellHookMessage, NativeMethods.MSGFLT.MSGFLT_REMOVE);
153 | }
154 | }
155 | }
156 |
157 | void IWidget.Dispose()
158 | {
159 | }
160 |
161 | void IWidget.Refresh()
162 | {
163 | }
164 |
165 | #endregion
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/WindowSubclassingCSharp/WindowSubclassing.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text.RegularExpressions;
5 |
6 | namespace Windawesome
7 | {
8 | public class WindowSubclassing : IPlugin
9 | {
10 | private readonly Tuple[] ignoredPrograms; // (className, displayName)
11 | private Windawesome windawesome;
12 | private HashMultiSet[] subclassedWindows;
13 |
14 | private static readonly uint startWindowProcMessage;
15 | private static readonly uint stopWindowProcMessage;
16 |
17 | static WindowSubclassing()
18 | {
19 | // TODO: can use messages between WM_USER and 0x7FFF
20 | startWindowProcMessage = NativeMethods.RegisterWindowMessage("START_WINDOW_PROC");
21 | stopWindowProcMessage = NativeMethods.RegisterWindowMessage("STOP_WINDOW_PROC");
22 | }
23 |
24 | public WindowSubclassing(IEnumerable> ignoredPrograms)
25 | {
26 | this.ignoredPrograms = ignoredPrograms.ToArray();
27 | }
28 |
29 | private bool IsMatch(string cName, string dName)
30 | {
31 | return ignoredPrograms.Any(t => Regex.IsMatch(cName, t.Item1) && Regex.IsMatch(dName, t.Item2));
32 | }
33 |
34 | private void OnWorkspaceApplicationAdded(Workspace workspace, Window window)
35 | {
36 | if (workspace.Layout.LayoutName() == "Tile" || workspace.Layout.LayoutName() == "Full Screen")
37 | {
38 | if (!IsMatch(window.className, window.DisplayName))
39 | {
40 | if (Environment.Is64BitProcess && window.is64BitProcess)
41 | {
42 | if (subclassedWindows[workspace.id - 1].Add(window) == HashMultiSet.AddResult.AddedFirst)
43 | {
44 | NativeMethods.SubclassWindow64(windawesome.Handle, window.hWnd);
45 | }
46 | if (workspace.IsCurrentWorkspace)
47 | {
48 | NativeMethods.SendNotifyMessage(window.hWnd, startWindowProcMessage, UIntPtr.Zero, IntPtr.Zero);
49 | }
50 | }
51 | else if (!Environment.Is64BitOperatingSystem)
52 | {
53 | if (subclassedWindows[workspace.id - 1].Add(window) == HashMultiSet.AddResult.AddedFirst)
54 | {
55 | NativeMethods.SubclassWindow32(windawesome.Handle, window.hWnd);
56 | }
57 | if (workspace.IsCurrentWorkspace)
58 | {
59 | NativeMethods.SendNotifyMessage(window.hWnd, startWindowProcMessage, UIntPtr.Zero, IntPtr.Zero);
60 | }
61 | }
62 | }
63 | }
64 | }
65 |
66 | private void OnWorkspaceApplicationRemoved(Workspace workspace, Window window)
67 | {
68 | switch (subclassedWindows[workspace.id - 1].Remove(window))
69 | {
70 | case HashMultiSet.RemoveResult.RemovedLast:
71 | NativeMethods.UnsubclassWindow(window.hWnd);
72 | break;
73 | case HashMultiSet.RemoveResult.Removed:
74 | NativeMethods.SendNotifyMessage(window.hWnd, stopWindowProcMessage, UIntPtr.Zero, IntPtr.Zero);
75 | break;
76 | }
77 | }
78 |
79 | private void OnWorkspaceChangedFrom(Workspace workspace)
80 | {
81 | subclassedWindows[workspace.id - 1].Where(w => w.WorkspacesCount > 1).ForEach(w =>
82 | NativeMethods.SendNotifyMessage(w.hWnd, stopWindowProcMessage, UIntPtr.Zero, IntPtr.Zero));
83 | }
84 |
85 | private void OnWorkspaceChangedTo(Workspace workspace)
86 | {
87 | subclassedWindows[workspace.id - 1].Where(w => w.WorkspacesCount > 1).ForEach(w =>
88 | NativeMethods.SendNotifyMessage(w.hWnd, startWindowProcMessage, UIntPtr.Zero, IntPtr.Zero));
89 | }
90 |
91 | private void OnWorkspaceLayoutChanged(Workspace workspace, ILayout oldLayout)
92 | {
93 | if (workspace.Layout.LayoutName() != "Tile" && workspace.Layout.LayoutName() != "Full Screen")
94 | {
95 | subclassedWindows[workspace.id - 1].ForEach(w => OnWorkspaceApplicationRemoved(workspace, w));
96 | }
97 | }
98 |
99 | //private void Listen(Window window)
100 | //{
101 | // if (window.titlebar == State.SHOWN || window.windowBorders == State.SHOWN)
102 | // {
103 | // NativeMethods.SendNotifyMessage(window.hWnd, START_WINDOW_PROC_MESSAGE, UIntPtr.Zero, IntPtr.Zero);
104 | // }
105 | // else if (window.titlebar == State.HIDDEN && window.windowBorders == State.HIDDEN)
106 | // {
107 | // NativeMethods.SendNotifyMessage(window.hWnd, STOP_WINDOW_PROC_MESSAGE, UIntPtr.Zero, IntPtr.Zero);
108 | // }
109 | // else if (window.titlebar == State.AS_IS || window.windowBorders == State.AS_IS)
110 | // {
111 | // var style = NativeMethods.GetWindowStyleLongPtr(window.hWnd);
112 |
113 | // if ((style & NativeMethods.WS.WS_CAPTION) != 0 || (style & NativeMethods.WS.WS_SIZEBOX) != 0)
114 | // {
115 | // NativeMethods.SendNotifyMessage(window.hWnd, START_WINDOW_PROC_MESSAGE, UIntPtr.Zero, IntPtr.Zero);
116 | // }
117 | // }
118 | //}
119 |
120 | #region IPlugin Members
121 |
122 | void IPlugin.InitializePlugin(Windawesome windawesome)
123 | {
124 | Workspace.WorkspaceWindowAdded += OnWorkspaceApplicationAdded;
125 | Workspace.WorkspaceWindowRemoved += OnWorkspaceApplicationRemoved;
126 | //Workspace.WorkspaceChangedFrom += OnWorkspaceChangedFrom;
127 | //Workspace.WorkspaceChangedTo += OnWorkspaceChangedTo;
128 | Workspace.WorkspaceLayoutChanged += OnWorkspaceLayoutChanged;
129 | this.windawesome = windawesome;
130 |
131 | subclassedWindows = new HashMultiSet[windawesome.config.Workspaces.Length];
132 | for (var i = 0; i < windawesome.config.Workspaces.Length; i++)
133 | {
134 | subclassedWindows[i] = new HashMultiSet();
135 | }
136 | }
137 |
138 | void IPlugin.Dispose()
139 | {
140 | subclassedWindows.ForEach(set => set.ForEach(w => NativeMethods.UnsubclassWindow(w.hWnd)));
141 | }
142 |
143 | #endregion
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/Config/1-General Settings.py:
--------------------------------------------------------------------------------
1 | from System.Drawing import Color, Font
2 | from System.Linq import Enumerable
3 | from Windawesome import ILayout, TileLayout, FullScreenLayout, FloatingLayout, IPlugin, Workspace
4 | from Windawesome import Bar, LayoutWidget, WorkspacesWidget, ApplicationTabsWidget, SystemTrayWidget, CpuMonitorWidget, RamMonitorWidget, LaptopBatteryMonitorWidget, LanguageBarWidget, CurrentlyPlayingWidget, SeparatorWidget
5 | from Windawesome import LoggerPlugin, ShortcutsManager, InputLanguageChangerPlugin
6 | from Windawesome.NativeMethods import MOD
7 | from System import Tuple
8 | from System.Windows.Forms import Keys
9 |
10 | def onLayoutLabelClick():
11 | if windawesome.CurrentWorkspace.Layout.LayoutName() == "Full Screen":
12 | windawesome.CurrentWorkspace.ChangeLayout(FloatingLayout())
13 | elif windawesome.CurrentWorkspace.Layout.LayoutName() == "Floating":
14 | windawesome.CurrentWorkspace.ChangeLayout(TileLayout())
15 | else:
16 | windawesome.CurrentWorkspace.ChangeLayout(FullScreenLayout())
17 |
18 | config.WindowBorderWidth = 1
19 | config.WindowPaddedBorderWidth = 0
20 |
21 | config.CheckForUpdates = False
22 |
23 | workspacesWidgetForegroundColors = [Color.Yellow for i in range(0, 10)]
24 | workspacesWidgetForegroundColors[0] = Color.LightSeaGreen
25 | workspacesWidgetBackgroundColors = [Color.Black for i in range(0, 10)]
26 |
27 | config.Bars = Enumerable.ToArray[Bar]([
28 | Bar(windawesome.monitors[0],
29 | [
30 | WorkspacesWidget(
31 | normalForegroundColor = workspacesWidgetForegroundColors,
32 | normalBackgroundColor = workspacesWidgetBackgroundColors,
33 | highlightedForegroundColor = Color.DarkOrange,
34 | highlightedBackgroundColor = Color.Black,
35 | highlightedInactiveForegroundColor = Color.LightSeaGreen,
36 | highlightedInactiveBackgroundColor = Color.Black,
37 | flashingForegroundColor = Color.Black
38 | ),
39 | LayoutWidget(
40 | foregroundColor = Color.Gold,
41 | backgroundColor = Color.Black,
42 | onClick = onLayoutLabelClick
43 | )
44 | ],
45 |
46 | [
47 | SystemTrayWidget(),
48 | LanguageBarWidget(
49 | foregroundColor = Color.Gold,
50 | backgroundColor = Color.Black
51 | ),
52 | SeparatorWidget(
53 | foregroundColor = Color.Gold,
54 | backgroundColor = Color.Black
55 | ),
56 | DateTimeWidget("ddd, d-MMM", "", "", Color.Black, Color.Gold),
57 | SeparatorWidget(
58 | foregroundColor = Color.Gold,
59 | backgroundColor = Color.Black
60 | ),
61 | DateTimeWidget("h:mm tt", "", "", Color.Black, Color.Gold),
62 | ],
63 |
64 | [
65 | ApplicationTabsWidget(
66 | normalForegroundColor = Color.LightSeaGreen,
67 | normalBackgroundColor = Color.Black,
68 | highlightedForegroundColor = Color.DarkOrange,
69 | highlightedBackgroundColor = Color.Black,
70 | )
71 | ],
72 |
73 | backgroundColor = Color.Black,
74 | font = Font("Consolas", 11)
75 | ),
76 | Bar(windawesome.monitors[0],
77 | [
78 | WorkspacesWidget(
79 | normalForegroundColor = workspacesWidgetForegroundColors,
80 | normalBackgroundColor = workspacesWidgetBackgroundColors,
81 | highlightedForegroundColor = Color.DarkOrange,
82 | highlightedBackgroundColor = Color.Black,
83 | highlightedInactiveForegroundColor = Color.LightSeaGreen,
84 | highlightedInactiveBackgroundColor = Color.Black,
85 | flashingForegroundColor = Color.Black
86 | ),
87 | LayoutWidget(
88 | foregroundColor = Color.Gold,
89 | backgroundColor = Color.Black,
90 | onClick = onLayoutLabelClick
91 | )
92 | ],
93 |
94 | [
95 | SystemTrayWidget(True),
96 | LanguageBarWidget(
97 | foregroundColor = Color.Gold,
98 | backgroundColor = Color.Black
99 | ),
100 | SeparatorWidget(
101 | foregroundColor = Color.Gold,
102 | backgroundColor = Color.Black
103 | ),
104 | DateTimeWidget("ddd, d-MMM", "", "", Color.Black, Color.Gold),
105 | SeparatorWidget(
106 | foregroundColor = Color.Gold,
107 | backgroundColor = Color.Black
108 | ),
109 | DateTimeWidget("h:mm tt", "", "", Color.Black, Color.Gold),
110 | ],
111 |
112 | [
113 | ApplicationTabsWidget(
114 | normalForegroundColor = Color.LightSeaGreen,
115 | normalBackgroundColor = Color.Black,
116 | highlightedForegroundColor = Color.DarkOrange,
117 | highlightedBackgroundColor = Color.Black,
118 | )
119 | ],
120 |
121 | backgroundColor = Color.Black,
122 | font = Font("Consolas", 11)
123 | )
124 | ])
125 |
126 | config.Workspaces = Enumerable.ToArray[Workspace]([
127 | Workspace(windawesome.monitors[0], FloatingLayout(), [config.Bars[1]], name = 'main'),
128 | Workspace(windawesome.monitors[0], FullScreenLayout(), [config.Bars[0]], name = 'web'),
129 | Workspace(windawesome.monitors[0], FullScreenLayout(), [config.Bars[0]]),
130 | Workspace(windawesome.monitors[0], TileLayout(masterAreaAxis = TileLayout.LayoutAxis.TopToBottom, masterAreaWindowsCount = 2, masterAreaFactor = 0.5), [config.Bars[0]], name = 'chat'),
131 | Workspace(windawesome.monitors[0], FullScreenLayout(), [config.Bars[0]]),
132 | Workspace(windawesome.monitors[0], FullScreenLayout(), [config.Bars[0]]),
133 | Workspace(windawesome.monitors[0], FullScreenLayout(), [config.Bars[0]]),
134 | Workspace(windawesome.monitors[0], FullScreenLayout(), [config.Bars[0]], name = 'mail'),
135 | Workspace(windawesome.monitors[0], FullScreenLayout(), [config.Bars[0]], name = 'BC')
136 | ])
137 |
138 | config.StartingWorkspaces = [config.Workspaces[0]]
139 |
140 | config.Plugins = [
141 | #LoggerPlugin(logWorkspaceSwitching = True, logWindowMinimization = True, logWindowRestoration = True,
142 | # logActivation = True),
143 | ShortcutsManager(),
144 | InputLanguageChangerPlugin(["icoicq", "icoSKYPE", "icoGOOGLE", "icoChannel", "icoJabber"])
145 | ]
146 |
--------------------------------------------------------------------------------
/Windawesome/LoggerPlugin.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace Windawesome
5 | {
6 | public sealed class LoggerPlugin : IPlugin
7 | {
8 | private readonly bool logRuleMatching;
9 | private readonly bool logCreation;
10 | private readonly bool logDeletion;
11 | private readonly bool logWorkspaceSwitching;
12 | private readonly bool logWindowMinimization;
13 | private readonly bool logWindowRestoration;
14 | private readonly bool logActivation;
15 | private readonly StreamWriter writer;
16 | private Windawesome windawesome;
17 |
18 | public LoggerPlugin(string filename = "logplugin.txt", bool logRuleMatching = true, bool logCreation = false, bool logDeletion = false,
19 | bool logWorkspaceSwitching = false, bool logWindowMinimization = false, bool logWindowRestoration = false,
20 | bool logActivation = false)
21 | {
22 | this.logRuleMatching = logRuleMatching;
23 | this.logCreation = logCreation;
24 | this.logDeletion = logDeletion;
25 | this.logWorkspaceSwitching = logWorkspaceSwitching;
26 | this.logWindowMinimization = logWindowMinimization;
27 | this.logWindowRestoration = logWindowRestoration;
28 | this.logActivation = logActivation;
29 | writer = new StreamWriter(filename, true);
30 | }
31 |
32 | private void OnProgramRuleMatched(ProgramRule programRule, IntPtr hWnd, string className, string displayName, string processName, NativeMethods.WS style, NativeMethods.WS_EX exStyle)
33 | {
34 | if (programRule != null)
35 | {
36 | writer.WriteLine("MATCHED - class '{0}'; caption '{1}'; processName '{2}';",
37 | className, displayName, processName);
38 | writer.WriteLine("\tAGAINST RULE WITH class '{0}'; caption '{1}'; process name '{2}';",
39 | programRule.className, programRule.displayName, programRule.processName);
40 | writer.WriteLine("\tstyle contains: '{0}'; style not contains '{1}'; ex style contains '{2}'; ex style not contains '{3}'; is managed '{4}'",
41 | programRule.styleContains, programRule.styleNotContains, programRule.exStyleContains, programRule.exStyleNotContains, programRule.isManaged);
42 | }
43 | else
44 | {
45 | writer.WriteLine("COULD NOT MATCH - class '{0}'; caption '{1}'; processName '{2}' AGAINST ANY RULE",
46 | className, displayName, processName);
47 | }
48 | }
49 |
50 | private void OnWorkspaceWindowAdded(Workspace workspace, Window window)
51 | {
52 | writer.WriteLine("ADDED - class '{0}'; caption '{1}'; workspace '{2}'",
53 | window.className, window.DisplayName, workspace.id);
54 | }
55 |
56 | private void OnWorkspaceWindowRemoved(Workspace workspace, Window window)
57 | {
58 | writer.WriteLine("REMOVED - class '{0}'; caption '{1}'; workspace '{2}'",
59 | window.className, window.DisplayName, workspace.id);
60 | }
61 |
62 | private void OnWorkspaceWindowMinimized(Workspace workspace, Window window)
63 | {
64 | writer.WriteLine("MINIMIZED - class '{0}'; caption '{1}'; workspace '{2}'",
65 | window.className, window.DisplayName, workspace.id);
66 | }
67 |
68 | private void OnWorkspaceWindowRestored(Workspace workspace, Window window)
69 | {
70 | writer.WriteLine("RESTORED - class '{0}'; caption '{1}'; workspace '{2}'",
71 | window.className, window.DisplayName, workspace.id);
72 | }
73 |
74 | private void OnWorkspaceShown(Workspace workspace)
75 | {
76 | writer.WriteLine("Workspace '{0}' shown", workspace.id);
77 | }
78 |
79 | private void OnWorkspaceHidden(Workspace workspace)
80 | {
81 | writer.WriteLine("Workspace '{0}' hidden", workspace.id);
82 | }
83 |
84 | private void OnWorkspaceActivated(Workspace workspace)
85 | {
86 | writer.WriteLine("Workspace '{0}' activated", workspace.id);
87 | }
88 |
89 | private void OnWorkspaceDeactivated(Workspace workspace)
90 | {
91 | writer.WriteLine("Workspace '{0}' deactivated", workspace.id);
92 | }
93 |
94 | private void OnWindowActivated(IntPtr hWnd)
95 | {
96 | var window = windawesome.CurrentWorkspace.GetWindow(hWnd);
97 | if (window != null)
98 | {
99 | writer.WriteLine("ACTIVATED - class '{0}'; caption '{1}'; workspace '{2}'",
100 | window.className, window.DisplayName, windawesome.CurrentWorkspace.id);
101 | }
102 | else
103 | {
104 | writer.WriteLine("ACTIVATED - HWND '{0}'; caption '{1}'; workspace '{2}'",
105 | hWnd, NativeMethods.GetText(hWnd), windawesome.CurrentWorkspace.id);
106 | }
107 | }
108 |
109 | #region IPlugin Members
110 |
111 | void IPlugin.InitializePlugin(Windawesome windawesome)
112 | {
113 | this.windawesome = windawesome;
114 |
115 | if (logRuleMatching)
116 | {
117 | Windawesome.ProgramRuleMatched += OnProgramRuleMatched;
118 | }
119 | if (logCreation)
120 | {
121 | Workspace.WorkspaceWindowAdded += OnWorkspaceWindowAdded;
122 | }
123 | if (logDeletion)
124 | {
125 | Workspace.WorkspaceWindowRemoved += OnWorkspaceWindowRemoved;
126 | }
127 | if (logWorkspaceSwitching)
128 | {
129 | Workspace.WorkspaceShown += OnWorkspaceShown;
130 | Workspace.WorkspaceHidden += OnWorkspaceHidden;
131 | Workspace.WorkspaceActivated += OnWorkspaceActivated;
132 | Workspace.WorkspaceDeactivated += OnWorkspaceDeactivated;
133 | }
134 | if (logWindowMinimization)
135 | {
136 | Workspace.WorkspaceWindowMinimized += OnWorkspaceWindowMinimized;
137 | }
138 | if (logWindowRestoration)
139 | {
140 | Workspace.WorkspaceWindowRestored += OnWorkspaceWindowRestored;
141 | }
142 | if (logActivation)
143 | {
144 | Workspace.WindowActivatedEvent += OnWindowActivated;
145 | }
146 | }
147 |
148 | void IPlugin.Dispose()
149 | {
150 | writer.WriteLine("==========================================");
151 | writer.Close();
152 | }
153 |
154 | #endregion
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/Docs/API.txt:
--------------------------------------------------------------------------------
1 | IMPORTANT!!!
2 | This document is badly out of date. If you want to write a plugin/widget for Windawesome, I suggest you look at the code and see what methods are public so you know what you can use.
3 | If you just want to configure Windawesome, then the only functions you need are the public ones in Windawesome.cs - take a look at them. They are pretty self-explanatory, I think.
4 |
5 | Methods:
6 |
7 | Windawesome:
8 |
9 | void RefreshWindawesome()
10 | removes all windows that have died but Windawesome hasn't noticed, which will fix some problems with the Widgets which would be thinking that there are more windows
11 |
12 | void ChangeApplicationToWorkspace(IntPtr handle, int workspace)
13 | moves the specified window from the current workspace to the one specified in the second parameter
14 |
15 | void AddApplicationToWorkspace(IntPtr handle, int workspace)
16 | adds the specified window from the current workspace to the one specified in the second parameter
17 |
18 | void RemoveApplicationFromCurrentWorkspace(IntPtr handle)
19 | removes the specified window from the current workspace
20 |
21 | public void RemoveApplicationFromAllWorkspaces(IntPtr hWnd)
22 | removes the specified window from all workspaces - this is somewhat like making the window unmanaged by Windawesome
23 |
24 | void SwitchToWorkspace(int workspace, bool setForeground = true)
25 | switches the current workspace to the one specified in the first parameter. If the second parameter is true, the window highest in Z order of the new workspace is set as the foreground and active window, otherwise is not
26 |
27 | void ToggleShowHideWindowInTaskbar(IntPtr handle)
28 | toggles the visibility of a button in the Windows taskbar for this window
29 |
30 | void ToggleShowHideWindowTitlebar(IntPtr handle)
31 | toggles the visibility of this window's titlebar
32 |
33 | void ToggleShowHideWindowBorder(IntPtr handle)
34 | toggles the visibility of this window's border
35 |
36 | void ToggleTaskbarVisibility()
37 | toggles the visibility of Window's taskbar
38 |
39 | void SwitchToApplication(IntPtr handle)
40 | switches to the window with this handle on whichever workspace it is
41 |
42 | void RunApplication(string path, string arguments = "")
43 | runs the specified application. Even if Windawesome is run in elevated mode, the new application will not be elevated
44 |
45 | void RunOrShowApplication(string className, string path, string displayName = ".*", string arguments = "")
46 | if the application with the specified class and display name is running (both are regexes), it is switch to, on whichever workspace it is. If not, it is run with RunApplication
47 |
48 | void QuitApplication(IntPtr handle)
49 | quits the specified application
50 |
51 | void MinimizeApplication(IntPtr handle)
52 | minimizes the specified application
53 |
54 | bool SwitchToApplicationInCurrentWorkspace(IntPtr handle)
55 | switches to the specified application but only if it is in the current workspace. Returns true if the application was found on the current workspace and was switched to
56 |
57 | static void RegisterMessage(int message, HandleMessageDelegate targetHandler)
58 | tells Windawesome that if it gets a message with that number it should call the delegate provided. Useful for plugins and widgets
59 |
60 | static Bitmap GetWindowSmallIconAsBitmap(IntPtr handle)
61 | returns the small icon of a window as a Bitmap instance
62 |
63 | Bar:
64 |
65 | void OnWidgetControlsChanged(IWidget widget, Control[] oldControls, Control[] newControls)
66 | void OnSpanWidgetControlsRemoved(IWidget widget, Control[] controls)
67 | void OnSpanWidgetControlsAdded(IWidget widget, Control[] controls)
68 | void OnFixedWidthWidgetWidthChanged(IWidget widget)
69 | Label CreateLabel(string text, int xLocation, int width = -1)
70 |
71 | Events:
72 |
73 | Windawesome:
74 |
75 | delegate void LayoutUpdatedEventHandler()
76 | static event LayoutUpdatedEventHandler LayoutUpdated
77 | called when the layout is updated (e.g. changed from one layout to the other, the layout symbol is changed and so on)
78 |
79 | delegate void WindowTitleOrIconChangedEventHandler(Workspace workspace, Window window, string newText, Bitmap newIcon)
80 | static event WindowTitleOrIconChangedEventHandler WindowTitleOrIconChanged
81 | called when a window's text (which is in the specified workspace) has been changed to the new text or the icon has changed to the new icon
82 |
83 | delegate void WindowFlashingEventHandler(LinkedList> list)
84 | static event WindowFlashingEventHandler WindowFlashing
85 | called when a window is flashing in the Windows Taskbar. The argument passed is a list of all the Workspaces which contain this Window
86 |
87 | Workspace:
88 |
89 | delegate void WorkspaceApplicationAddedEventHandler(Workspace workspace, Window window)
90 | static event WorkspaceApplicationAddedEventHandler WorkspaceApplicationAdded
91 | called when an application is added to that workspace
92 |
93 | delegate void WorkspaceApplicationRemovedEventHandler(Workspace workspace, Window window)
94 | static event WorkspaceApplicationRemovedEventHandler WorkspaceApplicationRemoved
95 | called when an application is removed from that workspace
96 |
97 | delegate void WorkspaceApplicationMinimizedEventHandler(Workspace workspace, Window window)
98 | static event WorkspaceApplicationMinimizedEventHandler WorkspaceApplicationMinimized
99 | called when an application is minimized in that workspace
100 |
101 | delegate void WorkspaceApplicationRestoredEventHandler(Workspace workspace, Window window)
102 | static event WorkspaceApplicationRestoredEventHandler WorkspaceApplicationRestored
103 | called when an application is restored in that workspace
104 |
105 | delegate void WorkspaceChangedFromEventHandler(Workspace workspace)
106 | static event WorkspaceChangedFromEventHandler WorkspaceChangedFrom
107 | called when a workspace has been unswitched from
108 |
109 | delegate void WorkspaceChangedToEventHandler(Workspace workspace)
110 | static event WorkspaceChangedToEventHandler WorkspaceChangedTo
111 | called when a workspace has been switched to
112 |
113 | delegate void WorkspaceLayoutChangedEventHandler(Workspace workspace, ILayout oldLayout)
114 | static event WorkspaceLayoutChangedEventHandler WorkspaceLayoutChanged
115 | called when a workspace's layout has changed. The ILayout argument is the old layout
116 |
117 | delegate void WindowActivatedEventHandler(IntPtr handle)
118 | static event WindowActivatedEventHandler WindowActivatedEvent
119 | called when an application has been switched to
120 |
121 |
--------------------------------------------------------------------------------
/Windawesome/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Images\Icon missing.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
123 |
124 |
125 |
--------------------------------------------------------------------------------
/TileLayout/TileLayout.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {720B613C-08A1-44EB-A5C0-7F35A16D7EC6}
9 | Library
10 | Properties
11 | Windawesome
12 | TileLayout
13 | v4.0
14 | 512
15 | Client
16 |
17 |
18 | true
19 | ..\bin\x64\Debug\Layouts\
20 | DEBUG;TRACE
21 | full
22 | x64
23 | bin\Debug\TileLayout.dll.CodeAnalysisLog.xml
24 | true
25 | GlobalSuppressions.cs
26 | prompt
27 | MinimumRecommendedRules.ruleset
28 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
29 | false
30 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
31 | false
32 | false
33 | true
34 |
35 |
36 | ..\bin\x64\Release\Layouts\
37 |
38 |
39 | true
40 | none
41 | x64
42 | bin\Release\TileLayout.dll.CodeAnalysisLog.xml
43 | true
44 | GlobalSuppressions.cs
45 | prompt
46 | MinimumRecommendedRules.ruleset
47 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
48 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
49 | false
50 |
51 |
52 | true
53 | ..\bin\x86\Debug\Layouts\
54 | DEBUG;TRACE
55 | full
56 | x86
57 | bin\Debug\TileLayout.dll.CodeAnalysisLog.xml
58 | true
59 | GlobalSuppressions.cs
60 | prompt
61 | MinimumRecommendedRules.ruleset
62 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
63 | false
64 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
65 | false
66 | true
67 |
68 |
69 | ..\bin\x86\Release\Layouts\
70 |
71 |
72 | true
73 | none
74 | x86
75 | bin\Release\TileLayout.dll.CodeAnalysisLog.xml
76 | true
77 | GlobalSuppressions.cs
78 | prompt
79 | MinimumRecommendedRules.ruleset
80 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
81 | false
82 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
83 | false
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | {90BCA858-A66A-42BF-A560-F956550FF9FE}
96 | Windawesome
97 | False
98 |
99 |
100 |
101 |
108 |
--------------------------------------------------------------------------------
/ShortcutsManager/ShortcutsManager.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {F708858D-F410-437B-997E-1373E44C5DA4}
9 | Library
10 | Properties
11 | Windawesome
12 | ShortcutsManager
13 | v4.0
14 | 512
15 | Client
16 |
17 |
18 | true
19 | ..\bin\x64\Debug\Plugins\
20 | DEBUG;TRACE
21 | full
22 | x64
23 | bin\Debug\ShortcutsManager.dll.CodeAnalysisLog.xml
24 | true
25 | GlobalSuppressions.cs
26 | prompt
27 | MinimumRecommendedRules.ruleset
28 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
29 | true
30 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
31 | true
32 | true
33 |
34 |
35 | ..\bin\x64\Release\Plugins\
36 |
37 |
38 | true
39 | none
40 | x64
41 | bin\Release\ShortcutsManager.dll.CodeAnalysisLog.xml
42 | true
43 | GlobalSuppressions.cs
44 | prompt
45 | MinimumRecommendedRules.ruleset
46 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
47 | false
48 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
49 | false
50 |
51 |
52 | true
53 | ..\bin\x86\Debug\Plugins\
54 | DEBUG;TRACE
55 | full
56 | x86
57 | bin\Debug\ShortcutsManager.dll.CodeAnalysisLog.xml
58 | true
59 | GlobalSuppressions.cs
60 | prompt
61 | MinimumRecommendedRules.ruleset
62 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
63 | true
64 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
65 | true
66 | true
67 |
68 |
69 | ..\bin\x86\Release\Plugins\
70 |
71 |
72 | true
73 | none
74 | x86
75 | bin\Release\ShortcutsManager.dll.CodeAnalysisLog.xml
76 | true
77 | GlobalSuppressions.cs
78 | prompt
79 | MinimumRecommendedRules.ruleset
80 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
81 | false
82 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
83 | false
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | {90BCA858-A66A-42BF-A560-F956550FF9FE}
96 | Windawesome
97 | False
98 |
99 |
100 |
101 |
108 |
--------------------------------------------------------------------------------
/Windawesome/Utilities.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Drawing;
4 | using System.Runtime.InteropServices;
5 | using System.Threading.Tasks;
6 |
7 | namespace Windawesome
8 | {
9 | public static class Utilities
10 | {
11 | public static void MoveMouseToMiddleOf(Rectangle bounds)
12 | {
13 | NativeMethods.SetCursorPos((bounds.Left + bounds.Right) / 2, (bounds.Top + bounds.Bottom) / 2);
14 | }
15 |
16 | public static IntPtr GetRootOwner(IntPtr hWnd)
17 | {
18 | var result = hWnd;
19 | hWnd = NativeMethods.GetWindow(hWnd, NativeMethods.GW.GW_OWNER);
20 | while (hWnd != IntPtr.Zero && hWnd != result)
21 | {
22 | result = hWnd;
23 | hWnd = NativeMethods.GetWindow(hWnd, NativeMethods.GW.GW_OWNER);
24 | }
25 | return result;
26 | }
27 |
28 | public static IntPtr DoForSelfAndOwnersWhile(IntPtr hWnd, Predicate action)
29 | {
30 | while (hWnd != IntPtr.Zero && action(hWnd))
31 | {
32 | hWnd = NativeMethods.GetWindow(hWnd, NativeMethods.GW.GW_OWNER);
33 | }
34 | return hWnd;
35 | }
36 |
37 | // http://blogs.msdn.com/b/oldnewthing/archive/2007/10/08/5351207.aspx
38 | // http://stackoverflow.com/questions/210504/enumerate-windows-like-alt-tab-does
39 | public static bool IsAltTabWindow(IntPtr hWnd)
40 | {
41 | var exStyle = NativeMethods.GetWindowExStyleLongPtr(hWnd);
42 | if (exStyle.HasFlag(NativeMethods.WS_EX.WS_EX_TOOLWINDOW) ||
43 | NativeMethods.GetWindow(hWnd, NativeMethods.GW.GW_OWNER) != IntPtr.Zero)
44 | {
45 | return false;
46 | }
47 | if (exStyle.HasFlag(NativeMethods.WS_EX.WS_EX_APPWINDOW))
48 | {
49 | return true;
50 | }
51 |
52 | // Start at the root owner
53 | var hWndTry = NativeMethods.GetAncestor(hWnd, NativeMethods.GA.GA_ROOTOWNER);
54 | IntPtr oldHWnd;
55 |
56 | // See if we are the last active visible popup
57 | do
58 | {
59 | oldHWnd = hWndTry;
60 | hWndTry = NativeMethods.GetLastActivePopup(hWndTry);
61 | }
62 | while (oldHWnd != hWndTry && !NativeMethods.IsWindowVisible(hWndTry));
63 |
64 | return hWndTry == hWnd;
65 | }
66 |
67 | public static bool IsAppWindow(IntPtr hWnd)
68 | {
69 | return NativeMethods.IsWindowVisible(hWnd) &&
70 | !NativeMethods.GetWindowExStyleLongPtr(hWnd).HasFlag(NativeMethods.WS_EX.WS_EX_NOACTIVATE) &&
71 | !NativeMethods.GetWindowStyleLongPtr(hWnd).HasFlag(NativeMethods.WS.WS_CHILD);
72 | }
73 |
74 | public static bool IsVisibleAndNotHung(Window window)
75 | {
76 | return NativeMethods.IsWindowVisible(window.hWnd) && WindowIsNotHung(window.hWnd);
77 | }
78 |
79 | public static bool WindowIsNotHung(Window window)
80 | {
81 | return WindowIsNotHung(window.hWnd);
82 | }
83 |
84 | public static bool WindowIsNotHung(IntPtr hWnd)
85 | {
86 | // IsHungAppWindow is not going to work, as it starts returning true 5 seconds after the window
87 | // has hung - so if a SetWindowPos, e.g., is called on such a window, it may block forever, even
88 | // though IsHungAppWindow returned false
89 |
90 | // SendMessageTimeout with a small timeout will timeout for some programs which are heavy on
91 | // computation and do not respond in time - like Visual Studio. A big timeout works, but if an
92 | // application is really hung, then Windawesome is blocked for this number of milliseconds.
93 | // That can be felt and is annoying. Perhaps the best scenario is:
94 | // return !IsHungAppWindow && (SendMessageTimeout(with_big_timeout) || GetLastWin32Error)
95 | // As this will not block forever at any point and it will only block the main thread for "with_big_timeout"
96 | // milliseconds the first 5 seconds when a program is hung - after that IsHungAppWindow catches it
97 | // immediately and returns. However, I decided that in most cases apps are not hung, so the overhead
98 | // of calling IsHungAppWindow AND SendMessageTimeout is not worth.
99 |
100 | return NativeMethods.SendMessageTimeout(hWnd, NativeMethods.WM_NULL, UIntPtr.Zero, IntPtr.Zero,
101 | NativeMethods.SMTO.SMTO_ABORTIFHUNG | NativeMethods.SMTO.SMTO_BLOCK, 3000, IntPtr.Zero) != IntPtr.Zero;
102 | }
103 |
104 | public static void QuitApplication(IntPtr hWnd)
105 | {
106 | NativeMethods.SendNotifyMessage(hWnd, NativeMethods.WM_SYSCOMMAND, NativeMethods.SC_CLOSE, IntPtr.Zero);
107 | }
108 |
109 | public static void MinimizeApplication(IntPtr hWnd)
110 | {
111 | NativeMethods.SendNotifyMessage(hWnd, NativeMethods.WM_SYSCOMMAND, NativeMethods.SC_MINIMIZE, IntPtr.Zero);
112 | }
113 |
114 | public static void MaximizeApplication(IntPtr hWnd)
115 | {
116 | NativeMethods.SendNotifyMessage(hWnd, NativeMethods.WM_SYSCOMMAND, NativeMethods.SC_MAXIMIZE, IntPtr.Zero);
117 | }
118 |
119 | public static void RestoreApplication(IntPtr hWnd)
120 | {
121 | NativeMethods.SendNotifyMessage(hWnd, NativeMethods.WM_SYSCOMMAND, NativeMethods.SC_RESTORE, IntPtr.Zero);
122 | }
123 |
124 | public static void RunApplication(string path, string arguments = "")
125 | {
126 | Task.Factory.StartNew(() =>
127 | {
128 | if (SystemAndProcessInformation.isAtLeastVista && SystemAndProcessInformation.isRunningElevated)
129 | {
130 | NativeMethods.RunApplicationNonElevated(path, arguments); // TODO: this is not working on XP
131 | }
132 | else
133 | {
134 | Process.Start(path, arguments);
135 | }
136 | });
137 | }
138 |
139 | public static void GetWindowSmallIconAsBitmap(IntPtr hWnd, Action action)
140 | {
141 | IntPtr result;
142 | NativeMethods.SendMessageTimeout(hWnd, NativeMethods.WM_GETICON, NativeMethods.ICON_SMALL,
143 | IntPtr.Zero, NativeMethods.SMTO.SMTO_BLOCK, 500, out result);
144 |
145 | if (result == IntPtr.Zero)
146 | {
147 | NativeMethods.SendMessageTimeout(hWnd, NativeMethods.WM_QUERYDRAGICON, UIntPtr.Zero,
148 | IntPtr.Zero, NativeMethods.SMTO.SMTO_BLOCK, 500, out result);
149 | }
150 |
151 | if (result == IntPtr.Zero)
152 | {
153 | result = NativeMethods.GetClassLongPtr(hWnd, NativeMethods.GCL_HICONSM);
154 | }
155 |
156 | if (result == IntPtr.Zero)
157 | {
158 | Task.Factory.StartNew(hWnd2 =>
159 | {
160 | Bitmap bitmap = null;
161 | try
162 | {
163 | int processId;
164 | NativeMethods.GetWindowThreadProcessId((IntPtr) hWnd2, out processId);
165 | var processFileName = Process.GetProcessById(processId).MainModule.FileName;
166 |
167 | var info = new NativeMethods.SHFILEINFO();
168 |
169 | NativeMethods.SHGetFileInfo(processFileName, 0, ref info,
170 | Marshal.SizeOf(info), NativeMethods.SHGFI_ICON | NativeMethods.SHGFI_SMALLICON);
171 |
172 | if (info.hIcon != IntPtr.Zero)
173 | {
174 | bitmap = new Bitmap(Bitmap.FromHicon(info.hIcon), SystemAndProcessInformation.smallIconSize);
175 | NativeMethods.DestroyIcon(info.hIcon);
176 | }
177 | else
178 | {
179 | var icon = Icon.ExtractAssociatedIcon(processFileName);
180 | if (icon != null)
181 | {
182 | bitmap = new Bitmap(icon.ToBitmap(), SystemAndProcessInformation.smallIconSize);
183 | }
184 | }
185 | }
186 | catch
187 | {
188 | }
189 |
190 | return bitmap;
191 | }, hWnd).ContinueWith(t => action(t.Result), TaskScheduler.FromCurrentSynchronizationContext());
192 | }
193 | else
194 | {
195 | Bitmap bitmap = null;
196 | try
197 | {
198 | bitmap = new Bitmap(Bitmap.FromHicon(result), SystemAndProcessInformation.smallIconSize);
199 | }
200 | catch
201 | {
202 | }
203 | action(bitmap);
204 | }
205 | }
206 | }
207 | }
208 |
--------------------------------------------------------------------------------
/Windawesome/SystemSettingsChanger.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Windawesome
4 | {
5 | internal static class SystemSettingsChanger
6 | {
7 | private static readonly NativeMethods.NONCLIENTMETRICS originalNonClientMetrics;
8 | private static readonly NativeMethods.ANIMATIONINFO originalAnimationInfo;
9 | private static readonly bool originalHideMouseWhenTyping;
10 | private static readonly bool originalFocusFollowsMouse;
11 | private static readonly bool originalFocusFollowsMouseSetOnTop;
12 |
13 | static SystemSettingsChanger()
14 | {
15 | originalNonClientMetrics = NativeMethods.NONCLIENTMETRICS.Default;
16 | NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_GETNONCLIENTMETRICS, originalNonClientMetrics.cbSize,
17 | ref originalNonClientMetrics, 0);
18 |
19 | originalAnimationInfo = NativeMethods.ANIMATIONINFO.Default;
20 | NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_GETANIMATION, originalAnimationInfo.cbSize,
21 | ref originalAnimationInfo, 0);
22 |
23 | NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_GETMOUSEVANISH, 0,
24 | ref originalHideMouseWhenTyping, 0);
25 |
26 | NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_GETACTIVEWINDOWTRACKING, 0,
27 | ref originalFocusFollowsMouse, 0);
28 |
29 | NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_GETACTIVEWNDTRKZORDER, 0,
30 | ref originalFocusFollowsMouseSetOnTop, 0);
31 | }
32 |
33 | public static void ApplyChanges(Config config)
34 | {
35 | System.Threading.Tasks.Task.Factory.StartNew(() =>
36 | {
37 | // set the "hide mouse when typing"
38 | if (config.HideMouseWhenTyping != originalHideMouseWhenTyping)
39 | {
40 | var hideMouseWhenTyping = config.HideMouseWhenTyping;
41 | NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETMOUSEVANISH, 0,
42 | ref hideMouseWhenTyping, 0);
43 |
44 | NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE,
45 | (UIntPtr) (uint) NativeMethods.SPI.SPI_SETMOUSEVANISH, IntPtr.Zero);
46 | }
47 |
48 | // set the "focus follows mouse"
49 | if (config.FocusFollowsMouse != originalFocusFollowsMouse)
50 | {
51 | var focusFollowsMouse = config.FocusFollowsMouse;
52 | NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETACTIVEWINDOWTRACKING, 0,
53 | ref focusFollowsMouse, 0);
54 |
55 | NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE,
56 | (UIntPtr) (uint) NativeMethods.SPI.SPI_SETACTIVEWINDOWTRACKING, IntPtr.Zero);
57 | }
58 |
59 | // set the "set window on top on focus follows mouse"
60 | if (config.FocusFollowsMouseSetOnTop != originalFocusFollowsMouseSetOnTop)
61 | {
62 | var focusFollowsMouseSetOnTop = config.FocusFollowsMouseSetOnTop;
63 | NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETACTIVEWNDTRKZORDER, 0,
64 | ref focusFollowsMouseSetOnTop, 0);
65 |
66 | NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE,
67 | (UIntPtr) (uint) NativeMethods.SPI.SPI_SETACTIVEWNDTRKZORDER, IntPtr.Zero);
68 | }
69 |
70 | // set the minimize/maximize/restore animations
71 | if ((originalAnimationInfo.iMinAnimate == 1 && !config.ShowMinimizeMaximizeRestoreAnimations) ||
72 | (originalAnimationInfo.iMinAnimate == 0 && config.ShowMinimizeMaximizeRestoreAnimations))
73 | {
74 | var animationInfo = originalAnimationInfo;
75 | animationInfo.iMinAnimate = config.ShowMinimizeMaximizeRestoreAnimations ? 1 : 0;
76 | NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETANIMATION, animationInfo.cbSize,
77 | ref animationInfo, 0);
78 |
79 | NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE,
80 | (UIntPtr) (uint) NativeMethods.SPI.SPI_SETANIMATION, IntPtr.Zero);
81 | }
82 |
83 | // set the global border and padded border widths
84 | if ((config.WindowBorderWidth >= 0 && originalNonClientMetrics.iBorderWidth != config.WindowBorderWidth) ||
85 | (SystemAndProcessInformation.isAtLeastVista && config.WindowPaddedBorderWidth >= 0 && originalNonClientMetrics.iPaddedBorderWidth != config.WindowPaddedBorderWidth))
86 | {
87 | var metrics = originalNonClientMetrics;
88 | metrics.iBorderWidth = config.WindowBorderWidth;
89 | metrics.iPaddedBorderWidth = config.WindowPaddedBorderWidth;
90 | NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETNONCLIENTMETRICS, metrics.cbSize,
91 | ref metrics, 0);
92 |
93 | NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE,
94 | (UIntPtr) (uint) NativeMethods.SPI.SPI_SETNONCLIENTMETRICS, IntPtr.Zero);
95 | }
96 | });
97 | }
98 |
99 | public static void RevertChanges(Config config)
100 | {
101 | var thread = new System.Threading.Thread(() => // this has to be a foreground thread
102 | {
103 | // revert the hiding of the mouse when typing
104 | if (config.HideMouseWhenTyping != originalHideMouseWhenTyping)
105 | {
106 | var hideMouseWhenTyping = originalHideMouseWhenTyping;
107 | NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETMOUSEVANISH, 0,
108 | ref hideMouseWhenTyping, NativeMethods.SPIF.SPIF_UPDATEINIFILE);
109 |
110 | NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE,
111 | (UIntPtr) (uint) NativeMethods.SPI.SPI_SETMOUSEVANISH, IntPtr.Zero);
112 | }
113 |
114 | // revert the "focus follows mouse"
115 | if (config.FocusFollowsMouse != originalFocusFollowsMouse)
116 | {
117 | var focusFollowsMouse = originalFocusFollowsMouse;
118 | NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETACTIVEWINDOWTRACKING, 0,
119 | ref focusFollowsMouse, NativeMethods.SPIF.SPIF_UPDATEINIFILE);
120 |
121 | NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE,
122 | (UIntPtr) (uint) NativeMethods.SPI.SPI_SETACTIVEWINDOWTRACKING, IntPtr.Zero);
123 | }
124 |
125 | // revert the "set window on top on focus follows mouse"
126 | if (config.FocusFollowsMouseSetOnTop != originalFocusFollowsMouseSetOnTop)
127 | {
128 | var focusFollowsMouseSetOnTop = originalFocusFollowsMouseSetOnTop;
129 | NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETACTIVEWNDTRKZORDER, 0,
130 | ref focusFollowsMouseSetOnTop, NativeMethods.SPIF.SPIF_UPDATEINIFILE);
131 |
132 | NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE,
133 | (UIntPtr) (uint) NativeMethods.SPI.SPI_SETACTIVEWNDTRKZORDER, IntPtr.Zero);
134 | }
135 |
136 | // revert the minimize/maximize/restore animations
137 | if ((originalAnimationInfo.iMinAnimate == 1 && !config.ShowMinimizeMaximizeRestoreAnimations) ||
138 | (originalAnimationInfo.iMinAnimate == 0 && config.ShowMinimizeMaximizeRestoreAnimations))
139 | {
140 | var animationInfo = originalAnimationInfo;
141 | NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETANIMATION, animationInfo.cbSize,
142 | ref animationInfo, NativeMethods.SPIF.SPIF_UPDATEINIFILE);
143 |
144 | NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE,
145 | (UIntPtr) (uint) NativeMethods.SPI.SPI_SETANIMATION, IntPtr.Zero);
146 | }
147 |
148 | // revert the size of non-client area of windows
149 | if ((config.WindowBorderWidth >= 0 && originalNonClientMetrics.iBorderWidth != config.WindowBorderWidth) ||
150 | (SystemAndProcessInformation.isAtLeastVista && config.WindowPaddedBorderWidth >= 0 && originalNonClientMetrics.iPaddedBorderWidth != config.WindowPaddedBorderWidth))
151 | {
152 | var metrics = originalNonClientMetrics;
153 | NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETNONCLIENTMETRICS, metrics.cbSize,
154 | ref metrics, NativeMethods.SPIF.SPIF_UPDATEINIFILE);
155 |
156 | NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE,
157 | (UIntPtr) (uint) NativeMethods.SPI.SPI_SETNONCLIENTMETRICS, IntPtr.Zero);
158 | }
159 | });
160 | thread.Start();
161 |
162 | new System.Threading.Timer(_ =>
163 | {
164 | // SystemParametersInfo sometimes hangs because of SPI_SETNONCLIENTMETRICS,
165 | // even though SPIF_SENDCHANGE is not added to the flags
166 | if (thread.IsAlive)
167 | {
168 | thread.Abort();
169 | Environment.Exit(0);
170 | }
171 | }, null, 5000, 0);
172 | }
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/Config/3-Hotkeys.rb:
--------------------------------------------------------------------------------
1 |
2 | def subscribe(modifiers, key)
3 | Windawesome::ShortcutsManager.subscribe modifiers, key, lambda {
4 | ret = yield
5 | return true if ret == nil
6 | ret
7 | }
8 | end
9 |
10 | flashing_window = nil
11 | previous_workspace = config.workspaces[0]
12 |
13 | def get_current_workspace_managed_window
14 | _, window, _ = windawesome.try_get_managed_window_for_workspace Windawesome::NativeMethods.get_foreground_window, windawesome.current_workspace
15 | window
16 | end
17 |
18 | Windawesome::Windawesome.window_flashing { |hWnd, l| flashing_window = hWnd }
19 |
20 | Windawesome::Workspace.workspace_deactivated { |ws| previous_workspace = ws }
21 |
22 | modifiers = Windawesome::ShortcutsManager::KeyModifiers
23 | key = System::Windows::Forms::Keys
24 |
25 | # quit Windawesome
26 | subscribe modifiers.Alt | modifiers.Shift, key.Q do
27 | windawesome.quit
28 | end
29 |
30 | # refresh Windawesome
31 | subscribe modifiers.Alt | modifiers.Shift, key.R do
32 | windawesome.refresh_windawesome
33 | end
34 |
35 | # quit application
36 | subscribe modifiers.Alt, key.Q do
37 | hWnd = Windawesome::NativeMethods.get_foreground_window
38 | Windawesome::Utilities.quit_application hWnd if Windawesome::NativeMethods.get_window_class_name(hWnd) != "WorkerW"
39 | end
40 |
41 | subscribe modifiers.Control | modifiers.Alt | modifiers.Shift, key.Q do
42 | windawesome.remove_application_from_workspace Windawesome::NativeMethods.get_foreground_window
43 | end
44 |
45 | # dismiss application
46 | subscribe modifiers.Alt, key.D do
47 | windawesome.dismiss_temporarily_shown_window Windawesome::NativeMethods.get_foreground_window
48 | end
49 |
50 | # minimize application
51 | subscribe modifiers.Alt, key.A do
52 | Windawesome::Utilities.minimize_application Windawesome::NativeMethods.get_foreground_window
53 | end
54 |
55 | # maximize or restore application
56 | subscribe modifiers.Alt, key.S do
57 | window = Windawesome::NativeMethods.get_foreground_window
58 | ws = Windawesome::NativeMethods.get_window_style_long_ptr.invoke window
59 | if ws.has_flag Windawesome::NativeMethods::WS.WS_MAXIMIZE
60 | Windawesome::Utilities.restore_application window
61 | elsif ws.has_flag Windawesome::NativeMethods::WS.WS_CAPTION and ws.has_flag Windawesome::NativeMethods::WS.WS_MAXIMIZEBOX
62 | Windawesome::Utilities.maximize_application window
63 | end
64 | end
65 |
66 | # switch to previous workspace
67 | subscribe modifiers.Alt, key.Oemtilde do
68 | windawesome.switch_to_workspace previous_workspace.id
69 | end
70 |
71 | # start Firefox
72 | subscribe modifiers.Alt, key.F do
73 | windawesome.run_or_show_application "^MozillaWindowClass$", "C:\\Program Files (x86)\\Pale Moon\\palemoon.exe"
74 | end
75 |
76 | # start Explorer
77 | subscribe modifiers.Alt, key.E do
78 | Windawesome::Utilities.run_application "C:\\Users\\Boris\\Desktop\\Downloads.lnk"
79 | end
80 |
81 | # start Hostile Takeover
82 | subscribe modifiers.Alt, key.H do
83 | Windawesome::Utilities.run_application "C:\\Program Files (x86)\\Vim\\vim73\\gvim.exe", "\"C:\\Users\\Boris\\Downloads\\Hostile Takeover.txt\""
84 | end
85 |
86 | # start Foobar2000
87 | subscribe modifiers.Alt, key.W do
88 | Windawesome::Utilities.run_application "C:\\Program Files (x86)\\foobar2000\\foobar2000.exe"
89 | end
90 |
91 | # start Cygwin's MinTTY shell
92 | subscribe modifiers.Alt | modifiers.Shift, key.Return do
93 | Windawesome::Utilities.run_application "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Cygwin\\Cygwin Terminal.lnk"
94 | end
95 |
96 | # start Bitcomet
97 | subscribe modifiers.Alt, key.B do
98 | Windawesome::Utilities.run_application "C:\\Program Files\\BitComet\\BitComet.exe"
99 | end
100 |
101 | # switch to flashing window
102 | subscribe modifiers.Alt, key.U do
103 | windawesome.switch_to_application flashing_window if flashing_window
104 | end
105 |
106 | # toggle window floating
107 | subscribe modifiers.Control | modifiers.Alt | modifiers.Shift, key.F do
108 | windawesome.toggle_window_floating Windawesome::NativeMethods.get_foreground_window
109 | end
110 |
111 | # toggle window titlebar
112 | subscribe modifiers.Alt | modifiers.Shift, key.D do
113 | windawesome.toggle_show_hide_window_titlebar Windawesome::NativeMethods.get_foreground_window
114 | end
115 |
116 | # toggle Windows taskbar
117 | subscribe modifiers.Alt | modifiers.Control, key.Space do
118 | windawesome.toggle_taskbar_visibility
119 | end
120 |
121 | # toggle window border
122 | subscribe modifiers.Alt | modifiers.Shift, key.B do
123 | windawesome.toggle_show_hide_window_border Windawesome::NativeMethods.get_foreground_window
124 | end
125 |
126 | # toggle window menu
127 | subscribe modifiers.Control | modifiers.Alt | modifiers.Shift, key.M do
128 | windawesome.toggle_show_hide_window_menu Windawesome::NativeMethods.get_foreground_window
129 | end
130 |
131 | # Layout stuff
132 |
133 | subscribe modifiers.Alt | modifiers.Shift, key.T do # change layout to Tile
134 | windawesome.current_workspace.change_layout Windawesome::TileLayout.new
135 | end
136 |
137 | subscribe modifiers.Alt | modifiers.Shift, key.M do # change layout to Full Screen
138 | windawesome.current_workspace.change_layout Windawesome::FullScreenLayout.new
139 | end
140 |
141 | subscribe modifiers.Alt | modifiers.Shift, key.F do # change layout to Floating
142 | windawesome.current_workspace.change_layout Windawesome::FloatingLayout.new
143 | end
144 |
145 | # window position stuff
146 |
147 | subscribe modifiers.Alt, key.J do
148 | window = get_current_workspace_managed_window
149 | if window
150 | next_window = windawesome.current_workspace.get_next_window window
151 | windawesome.switch_to_application next_window.hWnd if next_window
152 | elsif windawesome.current_workspace.get_windows_count > 0
153 | windawesome.switch_to_application windawesome.current_workspace.get_windows.first.value.hWnd
154 | end
155 | end
156 |
157 | subscribe modifiers.Alt, key.K do
158 | window = get_current_workspace_managed_window
159 | if window
160 | previous_window = windawesome.current_workspace.get_previous_window window
161 | windawesome.switch_to_application previous_window.hWnd if previous_window
162 | elsif windawesome.current_workspace.get_windows_count > 0
163 | windawesome.switch_to_application windawesome.current_workspace.get_windows.first.value.hWnd
164 | end
165 | end
166 |
167 | subscribe modifiers.Alt | modifiers.Shift, key.J do
168 | window = get_current_workspace_managed_window
169 | windawesome.current_workspace.shift_window_forward window if window
170 | end
171 |
172 | subscribe modifiers.Alt | modifiers.Shift, key.K do
173 | window = get_current_workspace_managed_window
174 | windawesome.current_workspace.shift_window_backwards window if window
175 | end
176 |
177 | subscribe modifiers.Control | modifiers.Alt | modifiers.Shift, key.Return do
178 | window = get_current_workspace_managed_window
179 | windawesome.current_workspace.shift_window_to_main_position window if window
180 | end
181 |
182 | # Tile Layout stuff
183 |
184 | subscribe modifiers.Alt | modifiers.Shift, key.L do
185 | windawesome.current_workspace.layout.toggle_layout_axis if windawesome.current_workspace.layout.layout_name == "Tile"
186 | end
187 |
188 | subscribe modifiers.Alt | modifiers.Shift, key.S do
189 | windawesome.current_workspace.layout.toggle_stack_area_axis if windawesome.current_workspace.layout.layout_name == "Tile"
190 | end
191 |
192 | subscribe modifiers.Control | modifiers.Alt | modifiers.Shift, key.S do
193 | windawesome.current_workspace.layout.toggle_master_area_axis if windawesome.current_workspace.layout.layout_name == "Tile"
194 | end
195 |
196 | subscribe modifiers.Alt | modifiers.Shift, key.Left do
197 | windawesome.current_workspace.layout.add_to_master_area_factor(-0.05) if windawesome.current_workspace.layout.layout_name == "Tile"
198 | end
199 |
200 | subscribe modifiers.Alt | modifiers.Shift, key.Right do
201 | windawesome.current_workspace.layout.add_to_master_area_factor if windawesome.current_workspace.layout.layout_name == "Tile"
202 | end
203 |
204 | # Workspaces stuff
205 |
206 | (1 .. config.workspaces.length).each do |i|
207 | k = eval("key.D" + i.to_s)
208 |
209 | subscribe modifiers.Alt, k do
210 | windawesome.switch_to_workspace i
211 | end
212 |
213 | subscribe modifiers.Alt | modifiers.Shift, k do
214 | windawesome.change_application_to_workspace Windawesome::NativeMethods.get_foreground_window, i
215 | end
216 |
217 | subscribe modifiers.Control | modifiers.Alt | modifiers.Shift, k do
218 | windawesome.add_application_to_workspace Windawesome::NativeMethods.get_foreground_window, i
219 | end
220 | end
221 |
--------------------------------------------------------------------------------
/ShortcutsManager/ShortcutsManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Windows.Forms;
6 |
7 | namespace Windawesome
8 | {
9 | public sealed class ShortcutsManager : IPlugin
10 | {
11 | private sealed class Subscription
12 | {
13 | private readonly Keys key;
14 | private readonly KeyModifiers modifiers;
15 |
16 | public Subscription(KeyModifiers modifiers, Keys key)
17 | {
18 | this.key = key;
19 | this.modifiers = modifiers;
20 | }
21 |
22 | public sealed class SubscriptionEqualityComparer : IEqualityComparer
23 | {
24 | #region IEqualityComparer Members
25 |
26 | bool IEqualityComparer.Equals(Subscription x, Subscription y)
27 | {
28 | if (((x.modifiers & KeyModifiers.Alt) != KeyModifiers.None ||
29 | (y.modifiers & KeyModifiers.Alt) != KeyModifiers.None) &&
30 | (x.modifiers & KeyModifiers.Alt & y.modifiers) == KeyModifiers.None)
31 | {
32 | return false;
33 | }
34 | if (((x.modifiers & KeyModifiers.Control) != KeyModifiers.None ||
35 | (y.modifiers & KeyModifiers.Control) != KeyModifiers.None) &&
36 | (x.modifiers & KeyModifiers.Control & y.modifiers) == KeyModifiers.None)
37 | {
38 | return false;
39 | }
40 | if (((x.modifiers & KeyModifiers.Shift) != KeyModifiers.None ||
41 | (y.modifiers & KeyModifiers.Shift) != KeyModifiers.None) &&
42 | (x.modifiers & KeyModifiers.Shift & y.modifiers) == KeyModifiers.None)
43 | {
44 | return false;
45 | }
46 | if (((x.modifiers & KeyModifiers.Win) != KeyModifiers.None ||
47 | (y.modifiers & KeyModifiers.Win) != KeyModifiers.None) &&
48 | (x.modifiers & KeyModifiers.Win & y.modifiers) == KeyModifiers.None)
49 | {
50 | return false;
51 | }
52 | return x.key == y.key;
53 | }
54 |
55 | int IEqualityComparer.GetHashCode(Subscription obj)
56 | {
57 | var modifiers = 0;
58 | if ((obj.modifiers & KeyModifiers.Alt) != KeyModifiers.None)
59 | {
60 | modifiers += 1;
61 | }
62 | if ((obj.modifiers & KeyModifiers.Control) != KeyModifiers.None)
63 | {
64 | modifiers += 2;
65 | }
66 | if ((obj.modifiers & KeyModifiers.Shift) != KeyModifiers.None)
67 | {
68 | modifiers += 4;
69 | }
70 | if ((obj.modifiers & KeyModifiers.Win) != KeyModifiers.None)
71 | {
72 | modifiers += 8;
73 | }
74 |
75 | return modifiers + 256 + (int) obj.key;
76 | }
77 |
78 | #endregion
79 | }
80 | }
81 |
82 | [Flags]
83 | public enum KeyModifiers
84 | {
85 | None = 0,
86 |
87 | LControl = 1,
88 | RControl = 2,
89 | Control = LControl | RControl,
90 |
91 | LShift = 4,
92 | RShift = 8,
93 | Shift = LShift | RShift,
94 |
95 | LAlt = 16,
96 | RAlt = 32,
97 | Alt = LAlt | RAlt,
98 |
99 | LWin = 64,
100 | RWin = 128,
101 | Win = LWin | RWin
102 | }
103 |
104 | public delegate bool KeyboardEventHandler();
105 | private static readonly NativeMethods.HookProc keyboardHookProcedure = KeyboardHookProc;
106 | private static readonly List registeredHotkeys;
107 | private static IntPtr hook;
108 | private static Dictionary subscriptions;
109 | private static bool hasKeyOnlySubscriptions;
110 |
111 | static ShortcutsManager()
112 | {
113 | registeredHotkeys = new List();
114 | }
115 |
116 | public static void Subscribe(KeyModifiers modifiers, Keys key, KeyboardEventHandler handler)
117 | {
118 | if ((modifiers & KeyModifiers.Control) == KeyModifiers.LControl ||
119 | (modifiers & KeyModifiers.Control) == KeyModifiers.RControl ||
120 | (modifiers & KeyModifiers.Alt) == KeyModifiers.LAlt ||
121 | (modifiers & KeyModifiers.Alt) == KeyModifiers.RAlt ||
122 | (modifiers & KeyModifiers.Shift) == KeyModifiers.LShift ||
123 | (modifiers & KeyModifiers.Shift) == KeyModifiers.RShift ||
124 | (modifiers & KeyModifiers.Win) == KeyModifiers.LWin ||
125 | (modifiers & KeyModifiers.Win) == KeyModifiers.RWin)
126 | {
127 | if (hook == IntPtr.Zero)
128 | {
129 | subscriptions = new Dictionary(new Subscription.SubscriptionEqualityComparer());
130 |
131 | hook = NativeMethods.SetWindowsHookEx(NativeMethods.WH_KEYBOARD_LL, keyboardHookProcedure,
132 | System.Diagnostics.Process.GetCurrentProcess().MainModule.BaseAddress, 0);
133 | }
134 |
135 | var newSubscription = new Subscription(modifiers, key);
136 | KeyboardEventHandler handlers;
137 | if (subscriptions.TryGetValue(newSubscription, out handlers))
138 | {
139 | subscriptions[newSubscription] = handlers + handler;
140 | }
141 | else
142 | {
143 | subscriptions[newSubscription] = handler;
144 | }
145 | }
146 | else
147 | {
148 | NativeMethods.MOD mods = 0;
149 | if (modifiers.HasFlag(KeyModifiers.Control))
150 | {
151 | mods |= NativeMethods.MOD.MOD_CONTROL;
152 | }
153 | if (modifiers.HasFlag(KeyModifiers.Alt))
154 | {
155 | mods |= NativeMethods.MOD.MOD_ALT;
156 | }
157 | if (modifiers.HasFlag(KeyModifiers.Shift))
158 | {
159 | mods |= NativeMethods.MOD.MOD_SHIFT;
160 | }
161 | if (modifiers.HasFlag(KeyModifiers.Win))
162 | {
163 | mods |= NativeMethods.MOD.MOD_WIN;
164 | }
165 | NativeMethods.RegisterHotKey(Windawesome.HandleStatic, registeredHotkeys.Count, mods, key);
166 | registeredHotkeys.Add(handler);
167 | }
168 |
169 | hasKeyOnlySubscriptions |= modifiers == KeyModifiers.None;
170 | }
171 |
172 | private static IntPtr KeyboardHookProc(int nCode, UIntPtr wParam, IntPtr lParam)
173 | {
174 | if (nCode == 0)
175 | {
176 | if (wParam == NativeMethods.WM_KEYDOWN || wParam == NativeMethods.WM_SYSKEYDOWN)
177 | {
178 | var key = (Keys) Marshal.ReadInt32(lParam);
179 | if (key != Keys.LShiftKey && key != Keys.RShiftKey &&
180 | key != Keys.LMenu && key != Keys.RMenu &&
181 | key != Keys.LControlKey && key != Keys.RControlKey &&
182 | key != Keys.LWin && key != Keys.RWin)
183 | {
184 | KeyModifiers modifiersPressed = 0;
185 | // there is no other way to distinguish between left and right modifier keys
186 | if ((NativeMethods.GetKeyState(Keys.LShiftKey) & 0x8000) == 0x8000)
187 | {
188 | modifiersPressed |= KeyModifiers.LShift;
189 | }
190 | if ((NativeMethods.GetKeyState(Keys.RShiftKey) & 0x8000) == 0x8000)
191 | {
192 | modifiersPressed |= KeyModifiers.RShift;
193 | }
194 | if ((NativeMethods.GetKeyState(Keys.LMenu) & 0x8000) == 0x8000)
195 | {
196 | modifiersPressed |= KeyModifiers.LAlt;
197 | }
198 | if ((NativeMethods.GetKeyState(Keys.RMenu) & 0x8000) == 0x8000)
199 | {
200 | modifiersPressed |= KeyModifiers.RAlt;
201 | }
202 | if ((NativeMethods.GetKeyState(Keys.LControlKey) & 0x8000) == 0x8000)
203 | {
204 | modifiersPressed |= KeyModifiers.LControl;
205 | }
206 | if ((NativeMethods.GetKeyState(Keys.RControlKey) & 0x8000) == 0x8000)
207 | {
208 | modifiersPressed |= KeyModifiers.RControl;
209 | }
210 | if ((NativeMethods.GetKeyState(Keys.LWin) & 0x8000) == 0x8000)
211 | {
212 | modifiersPressed |= KeyModifiers.LWin;
213 | }
214 | if ((NativeMethods.GetKeyState(Keys.RWin) & 0x8000) == 0x8000)
215 | {
216 | modifiersPressed |= KeyModifiers.RWin;
217 | }
218 |
219 | if (modifiersPressed != KeyModifiers.None || hasKeyOnlySubscriptions)
220 | {
221 | KeyboardEventHandler handlers;
222 | if (subscriptions.TryGetValue(new Subscription(modifiersPressed, key), out handlers))
223 | {
224 | if (handlers.GetInvocationList().Cast().Any(handler => handler()))
225 | {
226 | return NativeMethods.IntPtrOne;
227 | }
228 | }
229 | }
230 | }
231 | }
232 | }
233 |
234 | return NativeMethods.CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam);
235 | }
236 |
237 | #region IPlugin Members
238 |
239 | void IPlugin.InitializePlugin(Windawesome windawesome)
240 | {
241 | windawesome.RegisterMessage(NativeMethods.WM_HOTKEY,
242 | (ref Message m) => registeredHotkeys[m.WParam.ToInt32()]());
243 | }
244 |
245 | void IPlugin.Dispose()
246 | {
247 | if (hook != IntPtr.Zero)
248 | {
249 | NativeMethods.UnhookWindowsHookEx(hook);
250 | }
251 | Enumerable.Range(0, registeredHotkeys.Count).ForEach(i => NativeMethods.UnregisterHotKey(Windawesome.HandleStatic, i));
252 | }
253 |
254 | #endregion
255 | }
256 | }
257 |
--------------------------------------------------------------------------------
/Windawesome/WorkspacesWidget.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Linq;
5 | using System.Windows.Forms;
6 |
7 | namespace Windawesome
8 | {
9 | public sealed class WorkspacesWidget : IFixedWidthWidget
10 | {
11 | private Label[] workspaceLabels;
12 | private readonly Color[] normalForegroundColor;
13 | private readonly Color[] normalBackgroundColor;
14 | private readonly Color highlightedForegroundColor;
15 | private readonly Color highlightedBackgroundColor;
16 | private readonly Color highlightedInactiveForegroundColor;
17 | private readonly Color highlightedInactiveBackgroundColor;
18 | private readonly Color flashingForegroundColor;
19 | private readonly Color flashingBackgroundColor;
20 | private bool isLeft;
21 | private readonly bool flashWorkspaces;
22 |
23 | private static Windawesome windawesome;
24 | private static Timer flashTimer;
25 | private static Dictionary flashingWindows;
26 | private static HashSet flashingWorkspaces;
27 |
28 | private delegate void WorkFlashingStopped(Workspace workspace);
29 | private static event WorkFlashingStopped OnWorkspaceFlashingStopped;
30 |
31 | public WorkspacesWidget(IEnumerable normalForegroundColor = null, IEnumerable normalBackgroundColor = null,
32 | Color? highlightedForegroundColor = null, Color? highlightedBackgroundColor = null,
33 | Color? highlightedInactiveForegroundColor = null, Color? highlightedInactiveBackgroundColor = null,
34 | Color? flashingForegroundColor = null, Color? flashingBackgroundColor = null, bool flashWorkspaces = true)
35 | {
36 | this.normalForegroundColor = normalForegroundColor != null ? normalForegroundColor.ToArray() : new[]
37 | {
38 | Color.Black, Color.Black, Color.Black, Color.Black, Color.Black,
39 | Color.White, Color.White, Color.White, Color.White, Color.White
40 | };
41 | this.normalBackgroundColor = normalBackgroundColor != null ? normalBackgroundColor.ToArray() : new[]
42 | {
43 | Color.FromArgb(0xF0, 0xF0, 0xF0),
44 | Color.FromArgb(0xD8, 0xD8, 0xD8),
45 | Color.FromArgb(0xC0, 0xC0, 0xC0),
46 | Color.FromArgb(0xA8, 0xA8, 0xA8),
47 | Color.FromArgb(0x90, 0x90, 0x90),
48 | Color.FromArgb(0x78, 0x78, 0x78),
49 | Color.FromArgb(0x60, 0x60, 0x60),
50 | Color.FromArgb(0x48, 0x48, 0x48),
51 | Color.FromArgb(0x30, 0x30, 0x30),
52 | Color.FromArgb(0x18, 0x18, 0x18)
53 | };
54 | this.highlightedForegroundColor = highlightedForegroundColor ?? Color.White;
55 | this.highlightedBackgroundColor = highlightedBackgroundColor ?? Color.FromArgb(0x33, 0x99, 0xFF);
56 | this.highlightedInactiveForegroundColor = highlightedInactiveForegroundColor ?? Color.White;
57 | this.highlightedInactiveBackgroundColor = highlightedInactiveBackgroundColor ?? Color.Green;
58 | this.flashingForegroundColor = flashingForegroundColor ?? Color.White;
59 | this.flashingBackgroundColor = flashingBackgroundColor ?? Color.Red;
60 | this.flashWorkspaces = flashWorkspaces;
61 | if (flashWorkspaces)
62 | {
63 | if (flashTimer == null)
64 | {
65 | flashTimer = new Timer { Interval = 500 };
66 | flashingWindows = new Dictionary(3);
67 | flashingWorkspaces = new HashSet();
68 |
69 | Workspace.WorkspaceWindowRemoved += (_, w) => StopFlashingApplication(w.hWnd);
70 | Workspace.WindowActivatedEvent += StopFlashingApplication;
71 | Workspace.WorkspaceWindowRestored += (_, w) => StopFlashingApplication(w.hWnd);
72 | Windawesome.WindowFlashing += OnWindowFlashing;
73 | }
74 | }
75 | }
76 |
77 | private void OnWorkspaceLabelClick(object sender, EventArgs e)
78 | {
79 | windawesome.SwitchToWorkspace(Array.IndexOf(workspaceLabels, sender as Label) + 1);
80 | }
81 |
82 | private void SetWorkspaceLabelColor(Workspace workspace)
83 | {
84 | var workspaceLabel = workspaceLabels[workspace.id - 1];
85 | if (workspace.IsCurrentWorkspace)
86 | {
87 | workspaceLabel.BackColor = highlightedBackgroundColor;
88 | workspaceLabel.ForeColor = highlightedForegroundColor;
89 | }
90 | else if (workspace.IsWorkspaceVisible)
91 | {
92 | workspaceLabel.BackColor = highlightedInactiveBackgroundColor;
93 | workspaceLabel.ForeColor = highlightedInactiveForegroundColor;
94 | }
95 | else
96 | {
97 | var count = workspace.GetWindowsCount();
98 | if (count > 9)
99 | {
100 | count = 9;
101 | }
102 | workspaceLabel.BackColor = normalBackgroundColor[count];
103 | workspaceLabel.ForeColor = normalForegroundColor[count];
104 | }
105 | }
106 |
107 | private void OnWorkspaceChangedFromTo(Workspace workspace)
108 | {
109 | SetWorkspaceLabelColor(workspace);
110 | }
111 |
112 | private static void OnWindowFlashing(IntPtr hWnd, LinkedList> list)
113 | {
114 | if (list != null)
115 | {
116 | if (NativeMethods.IsWindow(hWnd) && !flashingWindows.ContainsKey(hWnd))
117 | {
118 | var foregroundWindow = NativeMethods.GetForegroundWindow();
119 |
120 | if (Utilities.DoForSelfAndOwnersWhile(foregroundWindow, h => h != hWnd) == IntPtr.Zero)
121 | {
122 | var workspace = list.First.Value.Item1;
123 |
124 | flashingWindows[hWnd] = workspace;
125 | flashingWorkspaces.Add(workspace);
126 | if (flashingWorkspaces.Count == 1)
127 | {
128 | flashTimer.Start();
129 | }
130 | }
131 | }
132 | }
133 | }
134 |
135 | private static void StopFlashingApplication(IntPtr hWnd)
136 | {
137 | Workspace workspace;
138 | if (flashingWindows.TryGetValue(hWnd, out workspace))
139 | {
140 | flashingWindows.Remove(hWnd);
141 | if (flashingWindows.Values.All(w => w != workspace))
142 | {
143 | OnWorkspaceFlashingStopped(workspace);
144 | flashingWorkspaces.Remove(workspace);
145 | if (flashingWorkspaces.Count == 0)
146 | {
147 | flashTimer.Stop();
148 | }
149 | }
150 | }
151 | }
152 |
153 | private void OnTimerTick(object sender, EventArgs e)
154 | {
155 | foreach (var flashingWorkspace in flashingWorkspaces)
156 | {
157 | if (workspaceLabels[flashingWorkspace.id - 1].BackColor == flashingBackgroundColor)
158 | {
159 | SetWorkspaceLabelColor(flashingWorkspace);
160 | }
161 | else
162 | {
163 | workspaceLabels[flashingWorkspace.id - 1].BackColor = flashingBackgroundColor;
164 | workspaceLabels[flashingWorkspace.id - 1].ForeColor = flashingForegroundColor;
165 | }
166 | }
167 | }
168 |
169 | #region IWidget Members
170 |
171 | void IWidget.StaticInitializeWidget(Windawesome windawesome)
172 | {
173 | WorkspacesWidget.windawesome = windawesome;
174 | }
175 |
176 | void IWidget.InitializeWidget(Bar bar)
177 | {
178 | if (flashWorkspaces)
179 | {
180 | flashTimer.Tick += OnTimerTick;
181 | OnWorkspaceFlashingStopped += SetWorkspaceLabelColor;
182 | }
183 |
184 | bar.BarShown += () => flashTimer.Start();
185 | bar.BarHidden += () => flashTimer.Stop();
186 |
187 | workspaceLabels = new Label[windawesome.config.Workspaces.Length];
188 |
189 | Workspace.WorkspaceWindowAdded += (ws, _) => SetWorkspaceLabelColor(ws);
190 | Workspace.WorkspaceWindowRemoved += (ws, _) => SetWorkspaceLabelColor(ws);
191 |
192 | Workspace.WorkspaceDeactivated += OnWorkspaceChangedFromTo;
193 | Workspace.WorkspaceActivated += OnWorkspaceChangedFromTo;
194 | Workspace.WorkspaceShown += OnWorkspaceChangedFromTo;
195 | Workspace.WorkspaceHidden += OnWorkspaceChangedFromTo;
196 |
197 | for (var i = 0; i < windawesome.config.Workspaces.Length; i++)
198 | {
199 | var workspace = windawesome.config.Workspaces[i];
200 | var name = workspace.name ?? (i + 1).ToString();
201 |
202 | var label = bar.CreateLabel(" " + name + " ", 0);
203 | label.TextAlign = ContentAlignment.MiddleCenter;
204 | label.Click += OnWorkspaceLabelClick;
205 | workspaceLabels[i] = label;
206 | SetWorkspaceLabelColor(workspace);
207 | }
208 | }
209 |
210 | IEnumerable IFixedWidthWidget.GetInitialControls(bool isLeft)
211 | {
212 | this.isLeft = isLeft;
213 |
214 | return workspaceLabels;
215 | }
216 |
217 | public void RepositionControls(int left, int right)
218 | {
219 | if (isLeft)
220 | {
221 | foreach (var label in workspaceLabels)
222 | {
223 | label.Location = new Point(left, 0);
224 | left += label.Width;
225 | }
226 | }
227 | else
228 | {
229 | foreach (var label in NativeMethods.Reverse(workspaceLabels))
230 | {
231 | right -= label.Width;
232 | label.Location = new Point(right, 0);
233 | }
234 | }
235 | }
236 |
237 | int IWidget.GetLeft()
238 | {
239 | return workspaceLabels.First().Left;
240 | }
241 |
242 | int IWidget.GetRight()
243 | {
244 | return workspaceLabels.Last().Right;
245 | }
246 |
247 | void IWidget.StaticDispose()
248 | {
249 | }
250 |
251 | void IWidget.Dispose()
252 | {
253 | }
254 |
255 | void IWidget.Refresh()
256 | {
257 | // remove all flashing windows
258 | flashingWindows.Keys.ToArray().ForEach(StopFlashingApplication);
259 | }
260 |
261 | #endregion
262 | }
263 | }
264 |
--------------------------------------------------------------------------------
/WindowSubclassingCSharp/WindowSubclassingCSharp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {3A9C3694-8057-43E3-B9B0-1487DBF80CB1}
9 | Library
10 | Properties
11 | Windawesome
12 | WindowSubclassingCSharp
13 | v4.0
14 | 512
15 | Client
16 |
17 |
18 | true
19 | ..\bin\x64\Debug\Plugins\
20 | DEBUG;TRACE
21 | full
22 | x64
23 | bin\Debug\WindowSubclassingCSharp.dll.CodeAnalysisLog.xml
24 | true
25 | GlobalSuppressions.cs
26 | prompt
27 | MinimumRecommendedRules.ruleset
28 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
29 | false
30 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
31 | false
32 |
33 |
34 | ..\bin\x64\Release\Plugins\
35 |
36 |
37 | true
38 | none
39 | x64
40 | bin\Release\WindowSubclassingCSharp.dll.CodeAnalysisLog.xml
41 | true
42 | GlobalSuppressions.cs
43 | prompt
44 | MinimumRecommendedRules.ruleset
45 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
46 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
47 |
48 |
49 | true
50 | ..\bin\x86\Debug\Plugins\
51 | DEBUG;TRACE
52 | full
53 | x86
54 | bin\Debug\WindowSubclassingCSharp.dll.CodeAnalysisLog.xml
55 | true
56 | GlobalSuppressions.cs
57 | prompt
58 | MinimumRecommendedRules.ruleset
59 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
60 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
61 |
62 |
63 | ..\bin\x86\Release\Plugins\
64 |
65 |
66 | true
67 | none
68 | x86
69 | bin\Release\WindowSubclassingCSharp.dll.CodeAnalysisLog.xml
70 | true
71 | GlobalSuppressions.cs
72 | prompt
73 | MinimumRecommendedRules.ruleset
74 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
75 | false
76 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
77 | false
78 |
79 |
80 | ..\bin\x64\Release Profiling\Plugins\
81 | true
82 | x64
83 | bin\Release\WindowSubclassingCSharp.dll.CodeAnalysisLog.xml
84 | true
85 | GlobalSuppressions.cs
86 | prompt
87 | MinimumRecommendedRules.ruleset
88 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
89 | true
90 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
91 | true
92 | full
93 | true
94 |
95 |
96 | ..\bin\x86\Release Profiling\Plugins\
97 | true
98 | x86
99 | bin\Release\WindowSubclassingCSharp.dll.CodeAnalysisLog.xml
100 | true
101 | GlobalSuppressions.cs
102 | prompt
103 | MinimumRecommendedRules.ruleset
104 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
105 | false
106 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
107 | false
108 | full
109 | true
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | {90BCA858-A66A-42BF-A560-F956550FF9FE}
122 | Windawesome
123 | False
124 |
125 |
126 |
127 |
134 |
--------------------------------------------------------------------------------
/Windawesome.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowSubclassing", "WindowSubclassing\WindowSubclassing.vcxproj", "{67670ECC-FD00-4B7C-8748-00A168FA9768}"
5 | EndProject
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SystemTrayHook", "SystemTrayHook\SystemTrayHook.vcxproj", "{4B1EDA49-44B3-49BC-9B5D-B3F602FDBDBD}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Windawesome", "Windawesome\Windawesome.csproj", "{90BCA858-A66A-42BF-A560-F956550FF9FE}"
9 | EndProject
10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Helpers", "Helpers\Helpers.vcxproj", "{B4A776E4-4C87-44B6-AFD6-A4996EE38330}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TileLayout", "TileLayout\TileLayout.csproj", "{720B613C-08A1-44EB-A5C0-7F35A16D7EC6}"
13 | EndProject
14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowSubclassingCSharp", "WindowSubclassingCSharp\WindowSubclassingCSharp.csproj", "{3A9C3694-8057-43E3-B9B0-1487DBF80CB1}"
15 | EndProject
16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShortcutsManager", "ShortcutsManager\ShortcutsManager.csproj", "{F708858D-F410-437B-997E-1373E44C5DA4}"
17 | EndProject
18 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GlobalShellHook", "GlobalShellHook\GlobalShellHook.vcxproj", "{A16BB20E-4E10-4C13-9BF4-F945FCE4E87C}"
19 | EndProject
20 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{354EF524-746F-47B0-B9F8-4A9C0F2DE872}"
21 | ProjectSection(SolutionItems) = preProject
22 | app_version.xml = app_version.xml
23 | EndProjectSection
24 | EndProject
25 | Global
26 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
27 | Debug|x64 = Debug|x64
28 | Debug|x86 = Debug|x86
29 | Profiling|x64 = Profiling|x64
30 | Profiling|x86 = Profiling|x86
31 | Release|x64 = Release|x64
32 | Release|x86 = Release|x86
33 | EndGlobalSection
34 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
35 | {67670ECC-FD00-4B7C-8748-00A168FA9768}.Debug|x64.ActiveCfg = Debug|x64
36 | {67670ECC-FD00-4B7C-8748-00A168FA9768}.Debug|x64.Build.0 = Debug|x64
37 | {67670ECC-FD00-4B7C-8748-00A168FA9768}.Debug|x86.ActiveCfg = Debug|Win32
38 | {67670ECC-FD00-4B7C-8748-00A168FA9768}.Debug|x86.Build.0 = Debug|Win32
39 | {67670ECC-FD00-4B7C-8748-00A168FA9768}.Profiling|x64.ActiveCfg = Release Profiling|x64
40 | {67670ECC-FD00-4B7C-8748-00A168FA9768}.Profiling|x64.Build.0 = Release Profiling|x64
41 | {67670ECC-FD00-4B7C-8748-00A168FA9768}.Profiling|x86.ActiveCfg = Release Profiling|Win32
42 | {67670ECC-FD00-4B7C-8748-00A168FA9768}.Profiling|x86.Build.0 = Release Profiling|Win32
43 | {67670ECC-FD00-4B7C-8748-00A168FA9768}.Release|x64.ActiveCfg = Release|x64
44 | {67670ECC-FD00-4B7C-8748-00A168FA9768}.Release|x64.Build.0 = Release|x64
45 | {67670ECC-FD00-4B7C-8748-00A168FA9768}.Release|x86.ActiveCfg = Release|Win32
46 | {67670ECC-FD00-4B7C-8748-00A168FA9768}.Release|x86.Build.0 = Release|Win32
47 | {4B1EDA49-44B3-49BC-9B5D-B3F602FDBDBD}.Debug|x64.ActiveCfg = Debug|x64
48 | {4B1EDA49-44B3-49BC-9B5D-B3F602FDBDBD}.Debug|x64.Build.0 = Debug|x64
49 | {4B1EDA49-44B3-49BC-9B5D-B3F602FDBDBD}.Debug|x86.ActiveCfg = Debug|Win32
50 | {4B1EDA49-44B3-49BC-9B5D-B3F602FDBDBD}.Debug|x86.Build.0 = Debug|Win32
51 | {4B1EDA49-44B3-49BC-9B5D-B3F602FDBDBD}.Profiling|x64.ActiveCfg = Debug|x64
52 | {4B1EDA49-44B3-49BC-9B5D-B3F602FDBDBD}.Profiling|x64.Build.0 = Debug|x64
53 | {4B1EDA49-44B3-49BC-9B5D-B3F602FDBDBD}.Profiling|x86.ActiveCfg = Debug|Win32
54 | {4B1EDA49-44B3-49BC-9B5D-B3F602FDBDBD}.Profiling|x86.Build.0 = Debug|Win32
55 | {4B1EDA49-44B3-49BC-9B5D-B3F602FDBDBD}.Release|x64.ActiveCfg = Release|x64
56 | {4B1EDA49-44B3-49BC-9B5D-B3F602FDBDBD}.Release|x64.Build.0 = Release|x64
57 | {4B1EDA49-44B3-49BC-9B5D-B3F602FDBDBD}.Release|x86.ActiveCfg = Release|Win32
58 | {4B1EDA49-44B3-49BC-9B5D-B3F602FDBDBD}.Release|x86.Build.0 = Release|Win32
59 | {90BCA858-A66A-42BF-A560-F956550FF9FE}.Debug|x64.ActiveCfg = Debug|x64
60 | {90BCA858-A66A-42BF-A560-F956550FF9FE}.Debug|x64.Build.0 = Debug|x64
61 | {90BCA858-A66A-42BF-A560-F956550FF9FE}.Debug|x86.ActiveCfg = Debug|x86
62 | {90BCA858-A66A-42BF-A560-F956550FF9FE}.Debug|x86.Build.0 = Debug|x86
63 | {90BCA858-A66A-42BF-A560-F956550FF9FE}.Profiling|x64.ActiveCfg = Debug|x64
64 | {90BCA858-A66A-42BF-A560-F956550FF9FE}.Profiling|x64.Build.0 = Debug|x64
65 | {90BCA858-A66A-42BF-A560-F956550FF9FE}.Profiling|x86.ActiveCfg = Debug|x86
66 | {90BCA858-A66A-42BF-A560-F956550FF9FE}.Profiling|x86.Build.0 = Debug|x86
67 | {90BCA858-A66A-42BF-A560-F956550FF9FE}.Release|x64.ActiveCfg = Release|x64
68 | {90BCA858-A66A-42BF-A560-F956550FF9FE}.Release|x64.Build.0 = Release|x64
69 | {90BCA858-A66A-42BF-A560-F956550FF9FE}.Release|x86.ActiveCfg = Release|x86
70 | {90BCA858-A66A-42BF-A560-F956550FF9FE}.Release|x86.Build.0 = Release|x86
71 | {B4A776E4-4C87-44B6-AFD6-A4996EE38330}.Debug|x64.ActiveCfg = Debug|x64
72 | {B4A776E4-4C87-44B6-AFD6-A4996EE38330}.Debug|x64.Build.0 = Debug|x64
73 | {B4A776E4-4C87-44B6-AFD6-A4996EE38330}.Debug|x86.ActiveCfg = Debug|Win32
74 | {B4A776E4-4C87-44B6-AFD6-A4996EE38330}.Debug|x86.Build.0 = Debug|Win32
75 | {B4A776E4-4C87-44B6-AFD6-A4996EE38330}.Profiling|x64.ActiveCfg = Debug|x64
76 | {B4A776E4-4C87-44B6-AFD6-A4996EE38330}.Profiling|x64.Build.0 = Debug|x64
77 | {B4A776E4-4C87-44B6-AFD6-A4996EE38330}.Profiling|x86.ActiveCfg = Debug|Win32
78 | {B4A776E4-4C87-44B6-AFD6-A4996EE38330}.Profiling|x86.Build.0 = Debug|Win32
79 | {B4A776E4-4C87-44B6-AFD6-A4996EE38330}.Release|x64.ActiveCfg = Release|x64
80 | {B4A776E4-4C87-44B6-AFD6-A4996EE38330}.Release|x64.Build.0 = Release|x64
81 | {B4A776E4-4C87-44B6-AFD6-A4996EE38330}.Release|x86.ActiveCfg = Release|Win32
82 | {B4A776E4-4C87-44B6-AFD6-A4996EE38330}.Release|x86.Build.0 = Release|Win32
83 | {720B613C-08A1-44EB-A5C0-7F35A16D7EC6}.Debug|x64.ActiveCfg = Debug|x64
84 | {720B613C-08A1-44EB-A5C0-7F35A16D7EC6}.Debug|x64.Build.0 = Debug|x64
85 | {720B613C-08A1-44EB-A5C0-7F35A16D7EC6}.Debug|x86.ActiveCfg = Debug|x86
86 | {720B613C-08A1-44EB-A5C0-7F35A16D7EC6}.Debug|x86.Build.0 = Debug|x86
87 | {720B613C-08A1-44EB-A5C0-7F35A16D7EC6}.Profiling|x64.ActiveCfg = Debug|x64
88 | {720B613C-08A1-44EB-A5C0-7F35A16D7EC6}.Profiling|x64.Build.0 = Debug|x64
89 | {720B613C-08A1-44EB-A5C0-7F35A16D7EC6}.Profiling|x86.ActiveCfg = Debug|x86
90 | {720B613C-08A1-44EB-A5C0-7F35A16D7EC6}.Profiling|x86.Build.0 = Debug|x86
91 | {720B613C-08A1-44EB-A5C0-7F35A16D7EC6}.Release|x64.ActiveCfg = Release|x64
92 | {720B613C-08A1-44EB-A5C0-7F35A16D7EC6}.Release|x64.Build.0 = Release|x64
93 | {720B613C-08A1-44EB-A5C0-7F35A16D7EC6}.Release|x86.ActiveCfg = Release|x86
94 | {720B613C-08A1-44EB-A5C0-7F35A16D7EC6}.Release|x86.Build.0 = Release|x86
95 | {3A9C3694-8057-43E3-B9B0-1487DBF80CB1}.Debug|x64.ActiveCfg = Debug|x64
96 | {3A9C3694-8057-43E3-B9B0-1487DBF80CB1}.Debug|x64.Build.0 = Debug|x64
97 | {3A9C3694-8057-43E3-B9B0-1487DBF80CB1}.Debug|x86.ActiveCfg = Debug|x86
98 | {3A9C3694-8057-43E3-B9B0-1487DBF80CB1}.Debug|x86.Build.0 = Debug|x86
99 | {3A9C3694-8057-43E3-B9B0-1487DBF80CB1}.Profiling|x64.ActiveCfg = Release Profiling|x64
100 | {3A9C3694-8057-43E3-B9B0-1487DBF80CB1}.Profiling|x64.Build.0 = Release Profiling|x64
101 | {3A9C3694-8057-43E3-B9B0-1487DBF80CB1}.Profiling|x86.ActiveCfg = Release Profiling|x86
102 | {3A9C3694-8057-43E3-B9B0-1487DBF80CB1}.Profiling|x86.Build.0 = Release Profiling|x86
103 | {3A9C3694-8057-43E3-B9B0-1487DBF80CB1}.Release|x64.ActiveCfg = Release|x64
104 | {3A9C3694-8057-43E3-B9B0-1487DBF80CB1}.Release|x64.Build.0 = Release|x64
105 | {3A9C3694-8057-43E3-B9B0-1487DBF80CB1}.Release|x86.ActiveCfg = Release|x86
106 | {3A9C3694-8057-43E3-B9B0-1487DBF80CB1}.Release|x86.Build.0 = Release|x86
107 | {F708858D-F410-437B-997E-1373E44C5DA4}.Debug|x64.ActiveCfg = Debug|x64
108 | {F708858D-F410-437B-997E-1373E44C5DA4}.Debug|x64.Build.0 = Debug|x64
109 | {F708858D-F410-437B-997E-1373E44C5DA4}.Debug|x86.ActiveCfg = Debug|x86
110 | {F708858D-F410-437B-997E-1373E44C5DA4}.Debug|x86.Build.0 = Debug|x86
111 | {F708858D-F410-437B-997E-1373E44C5DA4}.Profiling|x64.ActiveCfg = Debug|x64
112 | {F708858D-F410-437B-997E-1373E44C5DA4}.Profiling|x64.Build.0 = Debug|x64
113 | {F708858D-F410-437B-997E-1373E44C5DA4}.Profiling|x86.ActiveCfg = Debug|x86
114 | {F708858D-F410-437B-997E-1373E44C5DA4}.Profiling|x86.Build.0 = Debug|x86
115 | {F708858D-F410-437B-997E-1373E44C5DA4}.Release|x64.ActiveCfg = Release|x64
116 | {F708858D-F410-437B-997E-1373E44C5DA4}.Release|x64.Build.0 = Release|x64
117 | {F708858D-F410-437B-997E-1373E44C5DA4}.Release|x86.ActiveCfg = Release|x86
118 | {F708858D-F410-437B-997E-1373E44C5DA4}.Release|x86.Build.0 = Release|x86
119 | {A16BB20E-4E10-4C13-9BF4-F945FCE4E87C}.Debug|x64.ActiveCfg = Debug|x64
120 | {A16BB20E-4E10-4C13-9BF4-F945FCE4E87C}.Debug|x64.Build.0 = Debug|x64
121 | {A16BB20E-4E10-4C13-9BF4-F945FCE4E87C}.Debug|x86.ActiveCfg = Debug|Win32
122 | {A16BB20E-4E10-4C13-9BF4-F945FCE4E87C}.Debug|x86.Build.0 = Debug|Win32
123 | {A16BB20E-4E10-4C13-9BF4-F945FCE4E87C}.Profiling|x64.ActiveCfg = Debug|x64
124 | {A16BB20E-4E10-4C13-9BF4-F945FCE4E87C}.Profiling|x64.Build.0 = Debug|x64
125 | {A16BB20E-4E10-4C13-9BF4-F945FCE4E87C}.Profiling|x86.ActiveCfg = Debug|Win32
126 | {A16BB20E-4E10-4C13-9BF4-F945FCE4E87C}.Profiling|x86.Build.0 = Debug|Win32
127 | {A16BB20E-4E10-4C13-9BF4-F945FCE4E87C}.Release|x64.ActiveCfg = Release|x64
128 | {A16BB20E-4E10-4C13-9BF4-F945FCE4E87C}.Release|x64.Build.0 = Release|x64
129 | {A16BB20E-4E10-4C13-9BF4-F945FCE4E87C}.Release|x86.ActiveCfg = Release|Win32
130 | {A16BB20E-4E10-4C13-9BF4-F945FCE4E87C}.Release|x86.Build.0 = Release|Win32
131 | EndGlobalSection
132 | GlobalSection(SolutionProperties) = preSolution
133 | HideSolutionNode = FALSE
134 | EndGlobalSection
135 | EndGlobal
136 |
--------------------------------------------------------------------------------
/TileLayout/TileLayout.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Linq;
5 |
6 | namespace Windawesome
7 | {
8 | public sealed class TileLayout : ILayout
9 | {
10 | public enum LayoutAxis
11 | {
12 | LeftToRight,
13 | RightToLeft,
14 | TopToBottom,
15 | BottomToTop,
16 | Monocle
17 | }
18 |
19 | private Workspace workspace;
20 | private IEnumerable windows;
21 | private LayoutAxis layoutAxis;
22 | private LayoutAxis masterAreaAxis;
23 | private LayoutAxis stackAreaAxis;
24 | private double masterAreaFactor;
25 | private int masterAreaWindowsCount;
26 |
27 | public TileLayout(LayoutAxis layoutAxis = LayoutAxis.LeftToRight, LayoutAxis masterAreaAxis = LayoutAxis.Monocle,
28 | LayoutAxis stackAreaAxis = LayoutAxis.TopToBottom, double masterAreaFactor = 0.6, int masterAreaWindowsCount = 1)
29 | {
30 | this.layoutAxis = layoutAxis;
31 | this.masterAreaAxis = masterAreaAxis;
32 | this.stackAreaAxis = stackAreaAxis;
33 | if (masterAreaFactor > 1)
34 | {
35 | masterAreaFactor = 1;
36 | }
37 | else if (masterAreaFactor < 0)
38 | {
39 | masterAreaFactor = 0;
40 | }
41 | this.masterAreaFactor = masterAreaFactor;
42 | if (masterAreaWindowsCount < 0)
43 | {
44 | masterAreaWindowsCount = 0;
45 | }
46 | this.masterAreaWindowsCount = masterAreaWindowsCount;
47 | }
48 |
49 | #region API
50 |
51 | public void AddToMasterAreaWindowsCount(int count = 1)
52 | {
53 | masterAreaWindowsCount += count;
54 | if (masterAreaWindowsCount < 0)
55 | {
56 | masterAreaWindowsCount = 0;
57 | }
58 | this.Reposition();
59 | }
60 |
61 | public void ToggleLayoutAxis()
62 | {
63 | SetLayoutAxis((LayoutAxis) (((int) layoutAxis + 1) % Enum.GetValues(typeof(LayoutAxis)).Length));
64 | }
65 |
66 | public void ToggleMasterAreaAxis()
67 | {
68 | SetMasterAreaAxis((LayoutAxis) (((int) masterAreaAxis + 1) % Enum.GetValues(typeof(LayoutAxis)).Length));
69 | }
70 |
71 | public void ToggleStackAreaAxis()
72 | {
73 | SetStackAreaAxis((LayoutAxis) (((int) stackAreaAxis + 1) % Enum.GetValues(typeof(LayoutAxis)).Length));
74 | }
75 |
76 | public void SetLayoutAxis(LayoutAxis layoutAxis)
77 | {
78 | if (this.layoutAxis != layoutAxis)
79 | {
80 | this.layoutAxis = layoutAxis;
81 |
82 | this.Reposition();
83 | }
84 | }
85 |
86 | public void SetMasterAreaAxis(LayoutAxis masterAreaAxis)
87 | {
88 | if (this.masterAreaAxis != masterAreaAxis)
89 | {
90 | this.masterAreaAxis = masterAreaAxis;
91 |
92 | this.Reposition();
93 | }
94 | }
95 |
96 | public void SetStackAreaAxis(LayoutAxis stackAreaAxis)
97 | {
98 | if (this.stackAreaAxis != stackAreaAxis)
99 | {
100 | this.stackAreaAxis = stackAreaAxis;
101 |
102 | this.Reposition();
103 | }
104 | }
105 |
106 | public void AddToMasterAreaFactor(double masterAreaFactorChange = 0.05)
107 | {
108 | masterAreaFactor += masterAreaFactorChange;
109 | if (masterAreaFactor > 1)
110 | {
111 | masterAreaFactor = 1;
112 | }
113 | else if (masterAreaFactor < 0)
114 | {
115 | masterAreaFactor = 0;
116 | }
117 |
118 | this.Reposition();
119 | }
120 |
121 | #endregion
122 |
123 | private IntPtr PositionAreaWindows(IntPtr winPosInfo, Rectangle workingArea, bool master)
124 | {
125 | var count = master ?
126 | Math.Min(masterAreaWindowsCount, windows.Count()) :
127 | Math.Max(windows.Count() - masterAreaWindowsCount, 0);
128 | if (count > 0)
129 | {
130 | var otherWindowsCount = master ?
131 | Math.Max(windows.Count() - masterAreaWindowsCount, 0) :
132 | Math.Min(masterAreaWindowsCount, windows.Count());
133 | var factor = otherWindowsCount == 0 ? 1 : (master ? masterAreaFactor : 1 - masterAreaFactor);
134 | var axis = master ? masterAreaAxis : stackAreaAxis;
135 |
136 | int eachWidth = workingArea.Width, eachHight = workingArea.Height;
137 | int x = workingArea.X, y = workingArea.Y;
138 |
139 | switch (layoutAxis)
140 | {
141 | case LayoutAxis.LeftToRight:
142 | eachWidth = (int) (eachWidth * factor);
143 | x = master ? workingArea.X : workingArea.Right - eachWidth;
144 | break;
145 | case LayoutAxis.RightToLeft:
146 | eachWidth = (int) (eachWidth * factor);
147 | x = master ? workingArea.Right - eachWidth : workingArea.X;
148 | break;
149 | case LayoutAxis.TopToBottom:
150 | eachHight = (int) (eachHight * factor);
151 | y = master ? workingArea.Y : workingArea.Bottom - eachHight;
152 | break;
153 | case LayoutAxis.BottomToTop:
154 | eachHight = (int) (eachHight * factor);
155 | y = master ? workingArea.Bottom - eachHight : workingArea.Y;
156 | break;
157 | }
158 | switch (axis)
159 | {
160 | case LayoutAxis.RightToLeft:
161 | x += eachWidth;
162 | break;
163 | case LayoutAxis.BottomToTop:
164 | y += eachHight;
165 | break;
166 | }
167 | switch (axis)
168 | {
169 | case LayoutAxis.LeftToRight:
170 | case LayoutAxis.RightToLeft:
171 | eachWidth /= count;
172 | break;
173 | case LayoutAxis.TopToBottom:
174 | case LayoutAxis.BottomToTop:
175 | eachHight /= count;
176 | break;
177 | }
178 | switch (axis)
179 | {
180 | case LayoutAxis.RightToLeft:
181 | x -= eachWidth;
182 | break;
183 | case LayoutAxis.BottomToTop:
184 | y -= eachHight;
185 | break;
186 | }
187 |
188 | var masterOrStackWindows = master ? this.windows.Take(masterAreaWindowsCount) : this.windows.Skip(masterAreaWindowsCount);
189 | foreach (var window in masterOrStackWindows.Where(Utilities.WindowIsNotHung))
190 | {
191 | // TODO: this doesn't work for ICQ 7.5's windows. MoveWindow works in Debug mode, but not in Release
192 | winPosInfo = NativeMethods.DeferWindowPos(winPosInfo, window.hWnd, IntPtr.Zero,
193 | x, y, eachWidth, eachHight,
194 | NativeMethods.SWP.SWP_FRAMECHANGED | NativeMethods.SWP.SWP_NOACTIVATE | NativeMethods.SWP.SWP_NOCOPYBITS |
195 | NativeMethods.SWP.SWP_NOZORDER | NativeMethods.SWP.SWP_NOOWNERZORDER);
196 |
197 | switch (axis)
198 | {
199 | case LayoutAxis.LeftToRight:
200 | x += eachWidth;
201 | break;
202 | case LayoutAxis.RightToLeft:
203 | x -= eachWidth;
204 | break;
205 | case LayoutAxis.TopToBottom:
206 | y += eachHight;
207 | break;
208 | case LayoutAxis.BottomToTop:
209 | y -= eachHight;
210 | break;
211 | }
212 | }
213 | }
214 |
215 | return winPosInfo;
216 | }
217 |
218 | private static string GetAreaSymbol(int count, LayoutAxis axis)
219 | {
220 | switch (axis)
221 | {
222 | case LayoutAxis.LeftToRight:
223 | case LayoutAxis.RightToLeft:
224 | return "|";
225 | case LayoutAxis.TopToBottom:
226 | case LayoutAxis.BottomToTop:
227 | return "=";
228 | default: // LayoutAxis.Monocle
229 | return count.ToString();
230 | }
231 | }
232 |
233 | private void Reposition()
234 | {
235 | if (this.windows.Count() > 0)
236 | {
237 | var workingArea = workspace.Monitor.WorkingArea;
238 | var winPosInfo = NativeMethods.BeginDeferWindowPos(this.windows.Count());
239 | winPosInfo = PositionAreaWindows(winPosInfo, workingArea, true);
240 | winPosInfo = PositionAreaWindows(winPosInfo, workingArea, false);
241 | NativeMethods.EndDeferWindowPos(winPosInfo);
242 | }
243 |
244 | Workspace.DoLayoutUpdated();
245 | }
246 |
247 | #region ILayout Members
248 |
249 | string ILayout.LayoutSymbol()
250 | {
251 | if (layoutAxis == LayoutAxis.Monocle)
252 | {
253 | return "[" + workspace.GetWindowsCount() + "]";
254 | }
255 |
256 | var master = "[]";
257 | var stackCount = workspace.GetWindowsCount() - masterAreaWindowsCount;
258 |
259 | if (masterAreaWindowsCount > 1)
260 | {
261 | master = GetAreaSymbol(masterAreaWindowsCount, masterAreaAxis);
262 | }
263 | var stack = GetAreaSymbol(stackCount, stackAreaAxis);
264 |
265 | switch (layoutAxis)
266 | {
267 | case LayoutAxis.LeftToRight:
268 | case LayoutAxis.TopToBottom:
269 | return master + (master == "[]" ? "" : "]") + stack;
270 | case LayoutAxis.RightToLeft:
271 | case LayoutAxis.BottomToTop:
272 | return stack + (master == "[]" ? "" : "[") + master;
273 | }
274 |
275 | throw new Exception("Unreachable code... reached!");
276 | }
277 |
278 | public string LayoutName()
279 | {
280 | return "Tile";
281 | }
282 |
283 | bool ILayout.ShouldSaveAndRestoreSharedWindowsPosition()
284 | {
285 | return false;
286 | }
287 |
288 | void ILayout.Initialize(Workspace workspace)
289 | {
290 | this.workspace = workspace;
291 | }
292 |
293 | void ILayout.Dispose()
294 | {
295 | }
296 |
297 | void ILayout.Reposition()
298 | {
299 | // restore any maximized windows - should not use SW_RESTORE as it activates the window
300 | var hasMaximized = false;
301 | foreach (var window in workspace.GetLayoutManagedWindows().
302 | Where(w => NativeMethods.IsZoomed(w.hWnd) && Utilities.WindowIsNotHung(w)))
303 | {
304 | hasMaximized = true;
305 | NativeMethods.ShowWindow(window.hWnd, NativeMethods.SW.SW_SHOWNOACTIVATE);
306 | }
307 | if (hasMaximized)
308 | {
309 | System.Threading.Thread.Sleep(NativeMethods.minimizeRestoreDelay);
310 | }
311 |
312 | this.windows = workspace.GetLayoutManagedWindows();
313 | Reposition();
314 | }
315 |
316 | void ILayout.WindowMinimized(Window window)
317 | {
318 | (this as ILayout).WindowDestroyed(window);
319 | }
320 |
321 | void ILayout.WindowRestored(Window window)
322 | {
323 | (this as ILayout).WindowCreated(window);
324 | }
325 |
326 | void ILayout.WindowCreated(Window window)
327 | {
328 | if (workspace.IsWorkspaceVisible || window.WorkspacesCount == 1)
329 | {
330 | if (NativeMethods.IsZoomed(window.hWnd) && Utilities.WindowIsNotHung(window))
331 | {
332 | // restore if maximized - should not use SW_RESTORE as it activates the window
333 | NativeMethods.ShowWindow(window.hWnd, NativeMethods.SW.SW_SHOWNOACTIVATE);
334 | System.Threading.Thread.Sleep(NativeMethods.minimizeRestoreDelay);
335 | }
336 | if (workspace.IsWorkspaceVisible)
337 | {
338 | Reposition();
339 | }
340 | }
341 | }
342 |
343 | void ILayout.WindowDestroyed(Window window)
344 | {
345 | if (workspace.IsWorkspaceVisible)
346 | {
347 | Reposition();
348 | }
349 | }
350 |
351 | #endregion
352 | }
353 | }
354 |
--------------------------------------------------------------------------------