void IPlugin.InitializePlugin(Windawesome windawesome)
        {
            Workspace.WorkspaceWindowAdded += OnWorkspaceApplicationAdded;
            Workspace.WorkspaceWindowRemoved += OnWorkspaceApplicationRemoved;
            //Workspace.WorkspaceChangedFrom += OnWorkspaceChangedFrom;
            //Workspace.WorkspaceChangedTo += OnWorkspaceChangedTo;
            Workspace.WorkspaceLayoutChanged += OnWorkspaceLayoutChanged;
            this.windawesome = windawesome;

            subclassedWindows = new HashMultiSet<Window>[windawesome.config.Workspaces.Length];
            for (var i = 0; i < windawesome.config.Workspaces.Length; i++)
            {
                subclassedWindows[i] = new HashMultiSet<Window>();
            }
        }
Example #2
0
        internal Windawesome()
        {
            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();
            }
        }