Hide the workspace number

Feb 10, 2012 at 7:29 PM

hi,

first of all I want to thank you for windawesome! I've been using it for a few days now (switched from bug.n) and really like it.

My question is if there's any possibility to hide the numbers of the workspaces? Haven't found any function for this, yet.

Regards.

Coordinator
Feb 11, 2012 at 6:24 PM
Edited Feb 11, 2012 at 6:26 PM

Hello,

Unfortunately there isn't such functionality. You can try to implement it yourself if you know C# (look at WorkspacesWidget.cs) or wait for me some time and I will do it. :)

Regards!

P.S.

Actually, you only want to remove the numbers from the workspaces? I thought you wanted to not show the workspace label if there are no windows on it. Well, what you ask is trivial to implement, but it's not there for some reason. :) I will do it for the next version, but it might be a while. Sorry about that. :)

Feb 11, 2012 at 8:31 PM

hi,

thanks for the fast reply. No problem, I think I'm going to wait. Yepp, only want to remove the numbers, not the labels.

Another problem is that I just can't figure out how to set up a rule for miranda - want it to open at 3rd screen, but can't figure out the display or process name.

Currently looks like this: http://oi43.tinypic.com/15qvmmc.jpg

Config: http://pastebin.com/C08wu10U

Window rules: http://pastebin.com/arhz6bnh

 

also, is there any way to include the RAM usage and change the displayed text at the battery widget?

Still working on getting it colored.

Best tiling window manager I tried in windows so far!

Coordinator
Feb 13, 2012 at 6:41 AM

Hello,

I'm glad you like Windawesome. :) About your questions:

I see you use displayName to filter programs - this works (mostly), but is not the best thing. I suggest using className - in Windows every window has a so-called "class name" which cannot be changed. I guess the rules for Miranda don't work, because Miranda changes it's display name before it shows or something and that's why the rules don't capture it. Anyway, you should use some program like Spy++ (if you have Visual Studio) or WinSpy - with it, you can inspect any window and see its properties - you need the class name. Then use that in the rules and it will work (I know for Miranda for sure as I used to use it before - you can try getting one of the older versions a couple of months old and it should be there in the config).

About the RAM usage - it's not possible for now - there is no widget for that. And I don't think I'll have the time to do that. :) You could try modifying the Cpu monitor widget to do that and create a new widget that way. It should be relatively easy.

And I'm not sure about the display text in the battery widget - I'll take a look and see if I had forgotten to enable that customization.

So, good luck! :)

Feb 13, 2012 at 2:14 PM

hi,

many thanks, I downloaded winspy and changed most of the window rules to the class names. Gotta admit that I didn't know how to find the class names, that's why I used the display name.

Where can I find the cpu monitor widget?

At the moment the battery widget just shows C (charging) or B (battery) and I'd like to change it to "BAT:" so it looks like the CPU widget.

Regards and many thanks for your help :)

Coordinator
Feb 14, 2012 at 8:29 AM

Hi,

I am pretty sure that 99% of the users don't know what a window class name is. :) I didn't before I started writing this thing. :) I will definitely write some more information in the readme.

By "modifying" the Cpu monitor widget I meant modifying the code. :) I don't know if you want to do that/have the time. :) If you do - CpuMonitorWidget.cs or something in the source. :)

For all the customization that could be done you should look in the source directly - namely at the constructors of stuff that you are using. I am too lazy to write a proper documentation, that's why. :) For the Battery widget you should look here, namely:

string textForCharging = "C", string textForNotCharging = "B", string prefix = " ",
string postfix = "%", int updateTime = 60000, Color? backgroundColor = null,
Color? foregroundColor = null


This is the stuff that you can customize. Maybe I should write that in the documentation too... :D
Have fun!
Feb 14, 2012 at 1:26 PM
Edited Feb 14, 2012 at 4:18 PM

hi,

found it :D

Here's the code for the RamMonitorWidget:

 

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;

namespace Windawesome
{
    public sealed class RamMonitorWidget : IFixedWidthWidget
    {
        private Bar bar;

        private Label label;
        private bool isLeft;
        private readonly PerformanceCounter ramcounter;
        private readonly Timer updateTimer;
        private readonly string prefix;
        private readonly string postfix;
        private readonly Color backgroundColor;
        private readonly Color foregroundColor;

        public RamMonitorWidget(string prefix = "RAM:", string postfix = "MB", int updateTime = 1000,
            Color? backgroundColor = null, Color? foregroundColor = null)
        {
            updateTimer = new Timer { Interval = updateTime };
            updateTimer.Tick += OnTimerTick;

            this.prefix = prefix;
            this.postfix = postfix;

            this.backgroundColor = backgroundColor ?? Color.White;
            this.foregroundColor = foregroundColor ?? Color.Black;

            ramcounter = new PerformanceCounter("Memory", "Available MBytes");
        }

        private void OnTimerTick(object sender, EventArgs e)
        {
            var oldLeft = label.Left;
            var oldRight = label.Right;
            var nextValue = ramcounter.NextValue();

            label.Text = prefix + nextValue.ToString("00") + postfix;

            if (Math.Abs(nextValue - 100) < 0.00001)
            {
                this.RepositionControls(oldLeft, oldRight);
                bar.DoFixedWidthWidgetWidthChanged(this);
            }
        }

        #region IWidget Members

        void IWidget.StaticInitializeWidget(Windawesome windawesome)
        {
        }

        void IWidget.InitializeWidget(Bar bar)
        {
            this.bar = bar;

            label = bar.CreateLabel(prefix + ramcounter.NextValue().ToString("00") + postfix, 0);
            label.BackColor = backgroundColor;
            label.ForeColor = foregroundColor;
            label.TextAlign = ContentAlignment.MiddleCenter;

            bar.BarShown += () => updateTimer.Start();
            bar.BarHidden += () => updateTimer.Stop();
        }

        IEnumerable<Control> IFixedWidthWidget.GetInitialControls(bool isLeft)
        {
            this.isLeft = isLeft;

            return new[] { label };
        }

        public void RepositionControls(int left, int right)
        {
            this.label.Location = this.isLeft ? new Point(left, 0) : new Point(right - this.label.Width, 0);
        }

        int IWidget.GetLeft()
        {
            return label.Left;
        }

        int IWidget.GetRight()
        {
            return label.Right;
        }

        void IWidget.StaticDispose()
        {
        }

        void IWidget.Dispose()
        {
        }

        void IWidget.Refresh()
        {
        }

        #endregion
    }
}

Coordinator
Feb 14, 2012 at 9:41 PM

Hello,

OK, great, so you've found it and changed it already. :) I hope it works for you now. :) With your permission I could add that to Windawesome for the next version, and give you credit, of course.

Regards!

Feb 14, 2012 at 9:57 PM
Edited Feb 14, 2012 at 10:04 PM

hi,

sure you can use it. As you can see from the screenshot, I changed some labels after posting the code. Let me know if you also need the new code.

Also, I changed the colors and came across one issue: When entering an empty workspace I get that light grey/white bar in the middle (marked in the screenshot). You know where I can define the color for that one? Might help: The color of the miranda system tray icon background is exactly the same color, but I cannot find where this is defined.

http://oi40.tinypic.com/295ali9.jpg

EDIT: Still can't find where the workspaceID is connected with the workspace name/label. At some place the colon between the workspaceID and its name has to come into play, guess it's there where I can change/hide the workspaceID being shown.

Regards.

Feb 14, 2012 at 10:10 PM

before you use that code let me check if it is possible to display the used RAM and not the RAM that is still available (as it does at the moment). Going to post the code when I made it ;)

Coordinator
Feb 14, 2012 at 10:43 PM

Sure, I can wait. You can make it customizable - to be able to choose whether to show available or used RAM or something...

About the color - that should be either the Application Tabs Widget (if there are any shown) or the background color of the Bar itself - see in the Bar.cs file the constructor:

public Bar(Monitor monitor, IEnumerable<IFixedWidthWidget>leftAlignedWidgets,
IEnumerable<IFixedWidthWidget> rightAlignedWidgets,
IEnumerable<ISpanWidget> middleAlignedWidgets,
int barHeight = 20, Font font = null, Color? backgroundColor = null)

I think it should be one of the two.

The number next to the workspace name is shown in the WorkspacesWidget in the "InitializeWidget" method. You can just remove the concatenation of the number.

Have fun!

Feb 14, 2012 at 10:55 PM

don't think it is necessary to make this one customizable. Doing so would be the same as being able to decide whether the CpuMonitorWidget should show the current CPU speed or the available CPU speed.

I'm still trying to find out how to display the used memory instead of the available memory :-/

many thanks, going to have a look at the other stuff after I'm done with the RamMonitorWidget

 

Please note that this might take some time - never used Visual Studio, let alone C# before.

Feb 15, 2012 at 1:32 AM
Alien282 wrote:

Sure, I can wait. You can make it customizable - to be able to choose whether to show available or used RAM or something...

About the color - that should be either the Application Tabs Widget (if there are any shown) or the background color of the Bar itself - see in the Bar.cs file the constructor:

 

public Bar(Monitor monitor, IEnumerable<IFixedWidthWidget>leftAlignedWidgets,
IEnumerable<IFixedWidthWidget> rightAlignedWidgets,
IEnumerable<ISpanWidget> middleAlignedWidgets,
int barHeight = 20, Font font = null, Color? backgroundColor = null)

 

I think it should be one of the two.

The number next to the workspace name is shown in the WorkspacesWidget in the "InitializeWidget" method. You can just remove the concatenation of the number.

Have fun!

Changed the workspaceWidget and it's working quite good - numbers are gone

The background color of that bar is defined by the windows color for 3D Objects ;)

Going to work on the RamMonitorWidget tomorrow.

Feb 15, 2012 at 4:25 PM

Hey,

changed the Perfomance Counter to

ramcounter = new PerformanceCounter("Memory", "% Committed Bytes In Use");

Coordinator
Feb 16, 2012 at 4:35 PM

Great, thanks! I have zero time right now, but when I have, I'll incorporate your changes and they will be there in the new version. :)

So did you manage to change the color of the bar there in the middle?

If you have any more problems, do not hesitate to post. :)

Regards!

Feb 17, 2012 at 12:11 PM

no problems at all, it's just perfect for me now :D

http://oi40.tinypic.com/1zvy143.jpg

Many thanks again!

Feb 22, 2012 at 3:09 AM
Edited Feb 22, 2012 at 3:18 AM

EDIT, sry, got something wrong with the code

Coordinator
Feb 25, 2012 at 3:06 PM

Hello again,

I love your configuration! Could you please share it as I want to use the same color-scheme as yours? :)

Feb 27, 2012 at 8:31 AM
Edited Feb 27, 2012 at 8:37 AM

hi,

glad you like it ;D

changed the colors in the workspace widget:

 

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace Windawesome
{
	public sealed class WorkspacesWidget : IFixedWidthWidget
	{
		private Label[] workspaceLabels;
		private readonly Color[] normalForegroundColor;
		private readonly Color[] normalBackgroundColor;
		private readonly Color highlightedForegroundColor;
		private readonly Color highlightedBackgroundColor;
		private readonly Color highlightedInactiveForegroundColor;
		private readonly Color highlightedInactiveBackgroundColor;
		private readonly Color flashingForegroundColor;
		private readonly Color flashingBackgroundColor;
		private bool isLeft;
		private bool isShown;
		private readonly bool flashWorkspaces;

		private static Windawesome windawesome;
		private static Timer flashTimer;
		private static Dictionary<IntPtr, Workspace> flashingWindows;
		private static HashSet<Workspace> flashingWorkspaces;

		private delegate void WorkFlashingStopped(Workspace workspace);
		private static event WorkFlashingStopped OnWorkspaceFlashingStopped;

		public WorkspacesWidget(Color[] normalForegroundColor = null, Color[] normalBackgroundColor = null,
			Color? highlightedForegroundColor = null, Color? highlightedBackgroundColor = null,
			Color? highlightedInactiveForegroundColor = null, Color? highlightedInactiveBackgroundColor = null,
			Color? flashingForegroundColor = null, Color? flashingBackgroundColor = null, bool flashWorkspaces = true)
		{
			this.normalForegroundColor = normalForegroundColor ?? new[]
				{
					Color.MediumSeaGreen, Color.LightSeaGreen, Color.LightSeaGreen, Color.LightSeaGreen, Color.LightSeaGreen,
					Color.LightSeaGreen, Color.LightSeaGreen, Color.LightSeaGreen, Color.LightSeaGreen, Color.LightSeaGreen
				};
			this.normalBackgroundColor = normalBackgroundColor ?? new[]
				{
					Color.Black,
					Color.Black,
					Color.Black,
					Color.Black,
					Color.Black,
					Color.Black,
					Color.Black,
					Color.Black,
					Color.Black,
					Color.Black
				};
			this.highlightedForegroundColor = highlightedForegroundColor ?? Color.DarkOrange;
            this.highlightedBackgroundColor = highlightedBackgroundColor ?? Color.Black;
            this.highlightedInactiveForegroundColor = highlightedInactiveForegroundColor ?? Color.LightSeaGreen;
            this.highlightedInactiveBackgroundColor = highlightedInactiveBackgroundColor ?? Color.Black;
			this.flashingForegroundColor = flashingForegroundColor ?? Color.Black;
			this.flashingBackgroundColor = flashingBackgroundColor ?? Color.Red;
			this.flashWorkspaces = flashWorkspaces;
			if (flashWorkspaces)
			{
				if (flashTimer == null)
				{
					flashTimer = new Timer { Interval = 500 };
					flashingWindows = new Dictionary<IntPtr, Workspace>(3);
					flashingWorkspaces = new HashSet<Workspace>();

					Workspace.WorkspaceWindowRemoved += (_, w) => StopFlashingApplication(w.hWnd);
					Workspace.WindowActivatedEvent += StopFlashingApplication;
					Workspace.WorkspaceWindowRestored += (_, w) => StopFlashingApplication(w.hWnd);
					Windawesome.WindowFlashing += OnWindowFlashing;
				}
			}
		}

		private void OnWorkspaceLabelClick(object sender, EventArgs e)
		{
			windawesome.SwitchToWorkspace(Array.IndexOf(workspaceLabels, sender as Label) + 1);
		}

		private void SetWorkspaceLabelColor(Workspace workspace)
		{
			var workspaceLabel = workspaceLabels[workspace.id - 1];
			if (workspace.IsCurrentWorkspace && isShown)
			{
				workspaceLabel.BackColor = highlightedBackgroundColor;
				workspaceLabel.ForeColor = highlightedForegroundColor;
			}
			else if (workspace.IsWorkspaceVisible && isShown)
			{
				workspaceLabel.BackColor = highlightedInactiveBackgroundColor;
				workspaceLabel.ForeColor = highlightedInactiveForegroundColor;
			}
			else
			{
				var count = workspace.GetWindowsCount();
				if (count > 9)
				{
					count = 9;
				}
				workspaceLabel.BackColor = normalBackgroundColor[count];
				workspaceLabel.ForeColor = normalForegroundColor[count];
			}
		}

		private void OnWorkspaceChangedFromTo(Workspace workspace)
		{
			if (isShown)
			{
				SetWorkspaceLabelColor(workspace);
			}
		}

		private static void OnWindowFlashing(LinkedList<Tuple<Workspace, Window>> list)
		{
			var hWnd = list.First.Value.Item2.hWnd;
			var workspace = list.First.Value.Item1;
			if (NativeMethods.IsWindow(hWnd) && hWnd != NativeMethods.GetForegroundWindow() &&
				!flashingWindows.ContainsKey(hWnd))
			{
				flashingWindows[hWnd] = workspace;
				flashingWorkspaces.Add(workspace);
				if (flashingWorkspaces.Count == 1)
				{
					flashTimer.Start();
				}
			}
		}

		private static void StopFlashingApplication(IntPtr hWnd)
		{
			Workspace workspace;
			if (flashingWindows.TryGetValue(hWnd, out workspace))
			{
				flashingWindows.Remove(hWnd);
				if (flashingWindows.Values.All(w => w != workspace))
				{
					OnWorkspaceFlashingStopped(workspace);
					flashingWorkspaces.Remove(workspace);
					if (flashingWorkspaces.Count == 0)
					{
						flashTimer.Stop();
					}
				}
			}
		}

		private void OnTimerTick(object sender, EventArgs e)
		{
			if (isShown)
			{
				foreach (var flashingWorkspace in flashingWorkspaces)
				{
					if (workspaceLabels[flashingWorkspace.id - 1].BackColor == flashingBackgroundColor)
					{
						SetWorkspaceLabelColor(flashingWorkspace);
					}
					else
					{
						workspaceLabels[flashingWorkspace.id - 1].BackColor = flashingBackgroundColor;
						workspaceLabels[flashingWorkspace.id - 1].ForeColor = flashingForegroundColor;
					}
				}
			}
		}

		private void OnBarShown()
		{
			isShown = true;
			windawesome.monitors.ForEach(m => SetWorkspaceLabelColor(m.CurrentVisibleWorkspace));
		}

		private void OnBarHidden()
		{
			isShown = false;

			if (flashWorkspaces)
			{
				flashingWindows.Values.ForEach(SetWorkspaceLabelColor);
			}
			windawesome.monitors.ForEach(m => SetWorkspaceLabelColor(m.CurrentVisibleWorkspace));
		}

		#region IWidget Members

		void IWidget.StaticInitializeWidget(Windawesome windawesome)
		{
			WorkspacesWidget.windawesome = windawesome;
		}

		void IWidget.InitializeWidget(Bar bar)
		{
			if (flashWorkspaces)
			{
				flashTimer.Tick += OnTimerTick;
				OnWorkspaceFlashingStopped += SetWorkspaceLabelColor;
			}

			isShown = false;

			bar.BarShown += OnBarShown;
			bar.BarHidden += OnBarHidden;

			workspaceLabels = new Label[windawesome.config.Workspaces.Length];

			Workspace.WorkspaceWindowAdded += (ws, _) => SetWorkspaceLabelColor(ws);
			Workspace.WorkspaceWindowRemoved += (ws, _) => SetWorkspaceLabelColor(ws);

			Workspace.WorkspaceDeactivated += OnWorkspaceChangedFromTo;
			Workspace.WorkspaceActivated += OnWorkspaceChangedFromTo;
			Workspace.WorkspaceShown += OnWorkspaceChangedFromTo;
			Workspace.WorkspaceHidden += OnWorkspaceChangedFromTo;

			for (var i = 0; i < windawesome.config.Workspaces.Length; i++)
			{
				var workspace = windawesome.config.Workspaces[i];
				var name = (workspace.name == "" ? "" : " " + workspace.name);

				var label = bar.CreateLabel(" " + name + " ", 0);
				label.TextAlign = ContentAlignment.MiddleCenter;
				label.Click += OnWorkspaceLabelClick;
				workspaceLabels[i] = label;
				SetWorkspaceLabelColor(workspace);
			}
		}

		IEnumerable<Control> IFixedWidthWidget.GetInitialControls(bool isLeft)
		{
			this.isLeft = isLeft;

			return workspaceLabels;
		}

		public void RepositionControls(int left, int right)
		{
			if (isLeft)
			{
				foreach (var label in workspaceLabels)
				{
					label.Location = new Point(left, 0);
					left += label.Width;
				}
			}
			else
			{
				foreach (var label in NativeMethods.Reverse(workspaceLabels))
				{
					right -= label.Width;
					label.Location = new Point(right, 0);
				}
			}
		}

		int IWidget.GetLeft()
		{
			return workspaceLabels.First().Left;
		}

		int IWidget.GetRight()
		{
			return workspaceLabels.Last().Right;
		}

		void IWidget.StaticDispose()
		{
		}

		void IWidget.Dispose()
		{
		}

		void IWidget.Refresh()
		{
			// remove all flashing windows
			flashingWindows.Keys.ToArray().ForEach(StopFlashingApplication);
		}

		#endregion
	}
}

In all other widgets (DateTime, CPUMonitor, RamMonitor and LaptopBatteryMonitor) I changed the foregroundcolor to .DarkOrange and in the Bar.cs I changed the font to Consolas 8pt. BackgroundColor is defined as .Black in all widgets and the bar (changed the Bar.cs as well - didn't want it to read out the color from the windows config, so it's now defined in the cs).

 

Windawesome and Widget folder can be found here: http://www.mediafire.com/?8l7jtpv61urx2oy

Coordinator
Feb 27, 2012 at 9:14 PM

Hello,

Thanks for that! I've implemented it (with some changes) too. :)

btw, I think you've gone the (really) hard way. :) You have changed the colors/done the customizations in the C# code itself - while this is possible, the config files are exactly for that. :) The Python file General Settings is the place:

http://windawesome.codeplex.com/SourceControl/changeset/view/a0619b8a7dd8#Config%2f1-General%20Settings.py

And no recompilation is needed - just restart Windawesome and it will reread the config and start looking different. :)

Have fun and thanks again!

Mar 1, 2012 at 2:51 PM

hi,

I know, I just didn't get how to change it. I tried to change the bar background, but it kept using the windows color for 3D objects.

I'm now at a 2 screen display (laptop+screen) and just don't get how to run it with windawesome. Tried everything: Adding bars to both screens, adding workspaces to both screens and stuff, nothing worked. Could you please give me an example for the general settings file?

Also, is it possible to use the same settings file for a single/dual screen setup? e.g.: I switch off the second display and windawesome just doesn't use the "external" workspaces anymore?

When I detect the second screen windawesome just disappears, but is still running in my processes list.

Coordinator
Mar 1, 2012 at 8:11 PM

Hi,

One by one:

1. Look at my config files to see how to change everything through them. :)

2. For the dual-monitor-setup you have to make bars for each monitor, and assign each monitor at least one workspace. Then the workspaces will show their corresponding bars for that particular monitor. Read the usage file - there should be enough information there... I hope. :) I can give you an example but in Monday. :)

3. You can have the same settings file for a single/dual setup - I will show you that too in the example. You basically create the bars depending on the number of monitors, like:

if windawesome.monitors.Count == 1:

  config.Bars = sthg

else:

  config.Bars = something_else

Same thing for workspaces and starting workspaces.

4. DO NOT try to attach or detach a monitor while Windawesome is running - it will crash. :) Just quit Windawesome, add/remove the monitor, and then restart Windawesome. I just haven't had the chance to sit down and implement proper handling of that.

Regards!

Apr 23, 2012 at 10:27 AM

hey,

changed to 64 Bit system and now I'm using your config (except for some minor changes). 

Also I'm using it on my desktop now.

On my laptop it takes about 30MB of RAM and the battery decreases rapidly. Anyone else got that issue?

Coordinator
Apr 23, 2012 at 9:10 PM

Hello,

Well, that's strange. :) I have no idea why that might be. Is the average CPU usage high? You can check in the Resource Monitor.