public static void ApplyChanges(Config config) { System.Threading.Tasks.Task.Factory.StartNew(() => { // set the "hide mouse when typing" if (config.HideMouseWhenTyping != originalHideMouseWhenTyping) { var hideMouseWhenTyping = config.HideMouseWhenTyping; NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETMOUSEVANISH, 0, ref hideMouseWhenTyping, 0); NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE, (UIntPtr) (uint) NativeMethods.SPI.SPI_SETMOUSEVANISH, IntPtr.Zero); } // set the "focus follows mouse" if (config.FocusFollowsMouse != originalFocusFollowsMouse) { var focusFollowsMouse = config.FocusFollowsMouse; NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETACTIVEWINDOWTRACKING, 0, ref focusFollowsMouse, 0); NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE, (UIntPtr) (uint) NativeMethods.SPI.SPI_SETACTIVEWINDOWTRACKING, IntPtr.Zero); } // set the "set window on top on focus follows mouse" if (config.FocusFollowsMouseSetOnTop != originalFocusFollowsMouseSetOnTop) { var focusFollowsMouseSetOnTop = config.FocusFollowsMouseSetOnTop; NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETACTIVEWNDTRKZORDER, 0, ref focusFollowsMouseSetOnTop, 0); NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE, (UIntPtr) (uint) NativeMethods.SPI.SPI_SETACTIVEWNDTRKZORDER, IntPtr.Zero); } // set the minimize/maximize/restore animations if ((originalAnimationInfo.iMinAnimate == 1 && !config.ShowMinimizeMaximizeRestoreAnimations) || (originalAnimationInfo.iMinAnimate == 0 && config.ShowMinimizeMaximizeRestoreAnimations)) { var animationInfo = originalAnimationInfo; animationInfo.iMinAnimate = config.ShowMinimizeMaximizeRestoreAnimations ? 1 : 0; NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETANIMATION, animationInfo.cbSize, ref animationInfo, 0); NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE, (UIntPtr) (uint) NativeMethods.SPI.SPI_SETANIMATION, IntPtr.Zero); } // set the global border and padded border widths if ((config.WindowBorderWidth >= 0 && originalNonClientMetrics.iBorderWidth != config.WindowBorderWidth) || (SystemAndProcessInformation.isAtLeastVista && config.WindowPaddedBorderWidth >= 0 && originalNonClientMetrics.iPaddedBorderWidth != config.WindowPaddedBorderWidth)) { var metrics = originalNonClientMetrics; metrics.iBorderWidth = config.WindowBorderWidth; metrics.iPaddedBorderWidth = config.WindowPaddedBorderWidth; NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETNONCLIENTMETRICS, metrics.cbSize, ref metrics, 0); NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE, (UIntPtr) (uint) NativeMethods.SPI.SPI_SETNONCLIENTMETRICS, IntPtr.Zero); } }); }
internal Dawsome() { applications = new Dictionary<IntPtr, LinkedList<Tuple<Workspace, Window>>>(20); hiddenApplications = new HashMultiSet<IntPtr>(); messageHandlers = new Dictionary<int, HandleMessageDelegate>(2); monitors = Screen.AllScreens.Select((_, i) => new Monitor(i)).ToArray(); this.CreateHandle(new CreateParams { Parent = NativeMethods.HWND_MESSAGE, ClassName = "Message" }); HandleStatic = this.Handle; config = new Config(); config.LoadConfiguration(this); var startingWorkspacesCount = config.StartingWorkspaces.Count(); var distinctStartingWorkspaceMonitorsCount = config.StartingWorkspaces.Select(w => w.Monitor).Distinct().Count(); if (distinctStartingWorkspaceMonitorsCount != monitors.Length || distinctStartingWorkspaceMonitorsCount != startingWorkspacesCount) { throw new Exception("Each Monitor should have exactly one corresponding Workspace in StartingWorkspaces, i.e. " + "you should have as many Workspaces in StartingWorkspaces as you have Monitors!"); } CurrentWorkspace = config.StartingWorkspaces.First(w => w.Monitor.screen.Primary); topmostWindows = new WindowBase[config.Workspaces.Length]; Workspace.WindowActivatedEvent += h => topmostWindows[CurrentWorkspace.id - 1] = CurrentWorkspace.GetWindow(h) ?? new WindowBase(h); // add workspaces to their corresponding monitors monitors.ForEach(m => config.Workspaces.Where(w => w.Monitor == m).ForEach(m.AddWorkspace)); // n ^ 2 but hopefully fast enough // set starting workspaces for each monitor config.StartingWorkspaces.ForEach(w => w.Monitor.SetStartingWorkspace(w)); // initialize bars and plugins config.Bars.ForEach(b => b.InitializeBar(this)); config.Plugins.ForEach(p => p.InitializePlugin(this)); // add all windows to their respective workspaces NativeMethods.EnumWindows((hWnd, _) => (Utilities.IsAppWindow(hWnd) && AddWindowToWorkspace(hWnd, finishedInitializing: false)) || true, IntPtr.Zero); // add a handler for when the working area or screen rosolution changes as well as // a handler for the system shutting down/restarting SystemEvents.UserPreferenceChanged += OnUserPreferenceChanged; SystemEvents.DisplaySettingsChanged += OnDisplaySettingsChanged; SystemEvents.SessionEnding += OnSessionEnding; SystemSettingsChanger.ApplyChanges(config); // initialize all workspaces and hide windows not on StartingWorkspaces var windowsToHide = new HashSet<Window>(); foreach (var workspace in config.Workspaces) { workspace.GetWindows().ForEach(w => windowsToHide.Add(w)); workspace.Initialize(); topmostWindows[workspace.id - 1] = workspace.GetWindows().FirstOrDefault(w => !NativeMethods.IsIconic(w.hWnd)) ?? new WindowBase(NativeMethods.shellWindow); } windowsToHide.ExceptWith(config.StartingWorkspaces.SelectMany(ws => ws.GetWindows())); var winPosInfo = NativeMethods.BeginDeferWindowPos(windowsToHide.Count); winPosInfo = windowsToHide.Where(Utilities.WindowIsNotHung).Aggregate(winPosInfo, (current, w) => NativeMethods.DeferWindowPos(current, w.hWnd, IntPtr.Zero, 0, 0, 0, 0, NativeMethods.SWP.SWP_NOACTIVATE | NativeMethods.SWP.SWP_NOMOVE | NativeMethods.SWP.SWP_NOSIZE | NativeMethods.SWP.SWP_NOZORDER | NativeMethods.SWP.SWP_NOOWNERZORDER | NativeMethods.SWP.SWP_HIDEWINDOW)); NativeMethods.EndDeferWindowPos(winPosInfo); // remove windows from ALT-TAB menu and Taskbar config.StartingWorkspaces.Where(ws => ws != CurrentWorkspace).SelectMany(ws => ws.GetWindows()). Where(w => w.hideFromAltTabAndTaskbarWhenOnInactiveWorkspace).ForEach(w => w.ShowInAltTabAndTaskbar(false)); // initialize monitors and switch to the default starting workspaces monitors.ForEach(m => m.Initialize()); Monitor.ShowHideWindowsTaskbar(CurrentWorkspace.ShowWindowsTaskbar); DoForTopmostWindowForWorkspace(CurrentWorkspace, ActivateWindow); CurrentWorkspace.IsCurrentWorkspace = true; // register a shell hook NativeMethods.RegisterShellHookWindow(this.Handle); currentActiveWindow = NativeMethods.GetForegroundWindow(); // register some shell events winEventDelegate = WinEventDelegate; windowDestroyedShownOrHiddenWinEventHook = NativeMethods.SetWinEventHook(NativeMethods.EVENT.EVENT_OBJECT_DESTROY, NativeMethods.EVENT.EVENT_OBJECT_HIDE, IntPtr.Zero, winEventDelegate, 0, 0, NativeMethods.WINEVENT.WINEVENT_OUTOFCONTEXT | NativeMethods.WINEVENT.WINEVENT_SKIPOWNTHREAD); windowMinimizedOrRestoredWinEventHook = NativeMethods.SetWinEventHook(NativeMethods.EVENT.EVENT_SYSTEM_MINIMIZESTART, NativeMethods.EVENT.EVENT_SYSTEM_MINIMIZEEND, IntPtr.Zero, winEventDelegate, 0, 0, NativeMethods.WINEVENT.WINEVENT_OUTOFCONTEXT | NativeMethods.WINEVENT.WINEVENT_SKIPOWNTHREAD); windowFocusedWinEventHook = NativeMethods.SetWinEventHook(NativeMethods.EVENT.EVENT_SYSTEM_FOREGROUND, NativeMethods.EVENT.EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, winEventDelegate, 0, 0, NativeMethods.WINEVENT.WINEVENT_OUTOFCONTEXT | NativeMethods.WINEVENT.WINEVENT_SKIPOWNTHREAD); if (config.CheckForUpdates) { UpdateChecker.CheckForUpdate(); } }
public static void RevertChanges(Config config) { var thread = new System.Threading.Thread(() => // this has to be a foreground thread { // revert the hiding of the mouse when typing if (config.HideMouseWhenTyping != originalHideMouseWhenTyping) { var hideMouseWhenTyping = originalHideMouseWhenTyping; NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETMOUSEVANISH, 0, ref hideMouseWhenTyping, NativeMethods.SPIF.SPIF_UPDATEINIFILE); NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE, (UIntPtr) (uint) NativeMethods.SPI.SPI_SETMOUSEVANISH, IntPtr.Zero); } // revert the "focus follows mouse" if (config.FocusFollowsMouse != originalFocusFollowsMouse) { var focusFollowsMouse = originalFocusFollowsMouse; NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETACTIVEWINDOWTRACKING, 0, ref focusFollowsMouse, NativeMethods.SPIF.SPIF_UPDATEINIFILE); NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE, (UIntPtr) (uint) NativeMethods.SPI.SPI_SETACTIVEWINDOWTRACKING, IntPtr.Zero); } // revert the "set window on top on focus follows mouse" if (config.FocusFollowsMouseSetOnTop != originalFocusFollowsMouseSetOnTop) { var focusFollowsMouseSetOnTop = originalFocusFollowsMouseSetOnTop; NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETACTIVEWNDTRKZORDER, 0, ref focusFollowsMouseSetOnTop, NativeMethods.SPIF.SPIF_UPDATEINIFILE); NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE, (UIntPtr) (uint) NativeMethods.SPI.SPI_SETACTIVEWNDTRKZORDER, IntPtr.Zero); } // revert the minimize/maximize/restore animations if ((originalAnimationInfo.iMinAnimate == 1 && !config.ShowMinimizeMaximizeRestoreAnimations) || (originalAnimationInfo.iMinAnimate == 0 && config.ShowMinimizeMaximizeRestoreAnimations)) { var animationInfo = originalAnimationInfo; NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETANIMATION, animationInfo.cbSize, ref animationInfo, NativeMethods.SPIF.SPIF_UPDATEINIFILE); NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE, (UIntPtr) (uint) NativeMethods.SPI.SPI_SETANIMATION, IntPtr.Zero); } // revert the size of non-client area of windows if ((config.WindowBorderWidth >= 0 && originalNonClientMetrics.iBorderWidth != config.WindowBorderWidth) || (SystemAndProcessInformation.isAtLeastVista && config.WindowPaddedBorderWidth >= 0 && originalNonClientMetrics.iPaddedBorderWidth != config.WindowPaddedBorderWidth)) { var metrics = originalNonClientMetrics; NativeMethods.SystemParametersInfo(NativeMethods.SPI.SPI_SETNONCLIENTMETRICS, metrics.cbSize, ref metrics, NativeMethods.SPIF.SPIF_UPDATEINIFILE); NativeMethods.SendNotifyMessage(NativeMethods.HWND_BROADCAST, NativeMethods.WM_SETTINGCHANGE, (UIntPtr) (uint) NativeMethods.SPI.SPI_SETNONCLIENTMETRICS, IntPtr.Zero); } }); thread.Start(); new System.Threading.Timer(_ => { // SystemParametersInfo sometimes hangs because of SPI_SETNONCLIENTMETRICS, // even though SPIF_SENDCHANGE is not added to the flags if (thread.IsAlive) { thread.Abort(); Environment.Exit(0); } }, null, 5000, 0); }
public static void LoadAll(Dawsome dawsome, Config config, IEnumerable<FileInfo> files) { ScriptScope scope = null; ScriptEngine previousLanguage = null; foreach (var file in files) { var engine = GetEngineForFile(file); if (engine != null) { if (scope == null) { scope = engine.CreateScope(); scope.SetVariable("dawsome", dawsome); scope.SetVariable("config", config); } else if (previousLanguage != engine) { var oldScope = scope; scope = engine.CreateScope(); oldScope.GetItems(). Where(variable => variable.Value != null). ForEach(variable => scope.SetVariable(variable.Key, variable.Value)); previousLanguage.Runtime.Globals.GetItems(). Where(variable => variable.Value != null). ForEach(variable => scope.SetVariable(variable.Key, variable.Value)); } scope = engine.ExecuteFile(file.FullName, scope); previousLanguage = engine; } } }