Skip to content

Instantly share code, notes, and snippets.

@domsson
Created June 26, 2020 12:02
Show Gist options
  • Save domsson/ac47e52aa07ffbb455f013ce2eb86f2f to your computer and use it in GitHub Desktop.
Save domsson/ac47e52aa07ffbb455f013ce2eb86f2f to your computer and use it in GitHub Desktop.
blocks = "desktop | | dummy mem cpu volume updates datetime"
width = 816
height = 14
foreground = #bbbece
background = #2a2c41
line-width = 2
line-color = #7285b7
block-prefix = " "
font = 6x13
label-font = "-wuncon-siji-medium-r-normal--10-100-75-75-c-80-iso10646-1"
affix-font = "-xos4-terminesspowerline-medium-r-normal--12-120-72-72-c-60-iso10646-1"
[desktop]
command = "bspc query -D -d focused --names"
trigger = "bspc subscribe"
prefix = " "
suffix = " "
underline = true
[dummy]
command = "echo ' '"
background = #bbd984
affix-foreground = #bbd984
affix-background = #2a2c41
[mem]
command = "mem-proc -mus"
live = true
label = "  Mem "
min-width = 5
foreground = #352c38
background = #7ea3fd
label-foreground = #352c38
label-background = #7ea3fd
affix-foreground = #7ea3fd
affix-background = #bbd984
[cpu]
command = "cpu-proc -mus"
live = true
label = "  Cpu "
min-width = 5
foreground = #352c38
background = #c399e7
label-foreground = #352c38
label-background = #c399e7
affix-foreground = #c399e7
affix-background = #7ea3fd
[volume]
command = "volume-pulse -mus -w'muted'"
live = true
label = "  "
min-width = 5
foreground = #352c38
background = #fadb82
label-foreground = #352c38
label-background = #fadb82
affix-foreground = #fadb82
affix-background = #c399e7
[updates]
command = "echo ' 27'"
background = #c399e7
label = "  Updates: "
foreground = #ffffff
background = #f27975
label-foreground = #ffffff
label-background = #f27975
affix-foreground = #f27975
affix-background = #fadb82
[datetime]
command = "datetime -m -f'%a %b %d, %Y %I:%M%p'"
label = "  "
live = true
affix-foreground = #2a2c41
affix-background = #f27975
@domsson
Copy link
Author

domsson commented Jul 8, 2020

Yeah, command is the script or program to be run. Whatever you put in there (it could even just be a echo 'foo'), it needs to print text to stdout. That text will then be displayed on your bar.

Since you can't style parts of that output, you will have to resort to a bit of trickery in order to get the desired result. I'm not sure if this is the smartest way of going about it, but one idea is to split this into three blocks:

  1. shows the inactive workspaces to the left of the active workspace
  2. shows the active workspace (and will therefore get some different styling)
  3. shows the inactive workspaces to the right of the active workspace

So, something like this:

[bar]
blocks = "ws-left ws-active ws-right"

[ws-left]
command = "workspaces --left"
underline = false

[ws-active]
command = "workspaces --active"
underline = true

[ws-right]
command = "workspaces --right"
underline = false

Of course, the implementation of the fictional workspaces script/program is up to you, since I have no bloody idea how to fetch workspaces for XFCE. ;)


No idea regarding TrueType / OpenType. I think there is even more. I believe those are different standards / implementations of the same concept. Let's just say "vector based fonts" or "non-bitmap fonts" instead? ;) Edit: I searched it for 'ya.

@Joe23232
Copy link

Joe23232 commented Jul 8, 2020

Yeah, command is the script or program to be run. Whatever you put in there (it could even just be a echo 'foo'), it needs to print text to stdout. That text will then be displayed on your bar.

So I have already started working on a Rust code program and the executable is stored in this directory ~/home/test/Desktop/programming/bar/target/debug/bar

This is the code (for now I haven't finished it yet):

use std::process::Command;

fn main()
{
    // Initialize variables
    let some_text = "Testing 123";
    let colors = Colors
    {
        blue:   0x3b47f7,
        green:  0x14a03e,
        yellow: 0xc6e035,
        red:    0xdd382c,
    };

    let mut output = Command::new("sh");
    output.arg("-c").arg(format!("echo {} | lemonbar -p", some_text));
    output.status().expect("Error!");
}

struct Colors
{
    blue: u32,
    green: u32,
    yellow: u32,
    red: u32,
}

Since you can't style parts of that output, you will have to resort to a bit of trickery in order to get the desired result. I'm not sure if this is the smartest way of going about it, but one idea is to split this into three blocks:

Interesting, I will take a look into this but I think the best way is to just connect it to an external script?

With my current succade setup:

name = "testbar"
blocks = "desktop | user | cpu date time"
height = 24
foreground = "#ffffff"
background = "#2a2c41"
underline = true
line-width = 3
line-color = "#333333"
label-foreground = "#ffffff"
block-prefix = " " 
block-suffix = " "
block-margin = 4
font = 6x13
label-font = 6x13
bottom = true
block-prefix = " "
affix-font = "-xos4-terminesspowerline-medium-r-normal--12-120-72-72-c-60-iso10646-1"


[desktop]
command = "./~/Desktop/programming/bar/debug/bar"

[user]
command = "whoami"

[cpu]
command = "cpu-proc -mus"
live = true
label = "cpu "
background = #245ae2
affix-background = #245ae2
label-background = #245ae2

[date]
command = "date +'%Y-%m-%d'"
live = true

[time]
command = "date +'%H:%M:%S'"
interval = 1
mouse-left = xclock
margin-right = 8

Is it possible to connect [desktop] to my script using command to output all the workspaces with different colors for each workspace? I tried doing that but it is not working, is there something wrong with the syntax (in the succade code under command for [desktop]?

Of course, the implementation of the fictional workspaces script/program is up to you, since I have no bloody idea how to fetch workspaces for XFCE. ;)

By the way I plan to use spectrwm not xfce, xfce is just a temporary solution :)


No idea regarding TrueType / OpenType. I think there is even more. I believe those are different standards / implementations of the same concept. Let's just say "vector based fonts" or "non-bitmap fonts" instead? ;) Edit: I searched it for 'ya.

Thanks mate :)

@domsson
Copy link
Author

domsson commented Jul 8, 2020

Aaah. Okay, you just gave me a great idea. But, let me go a step back:

The reason it doesn't work is probably because succade does not expect to get lemonbar-style format strings from your script. So if your program outputs something like %{B#665544}foo bar%{B-}, then succade will escape the % characters. You should therefore see the entire format string on your bar. Is that what is happening or what do you mean by "it is not working"?

If my assumption is correct, then I could probably implement a new option, let's call it raw, that tells succade to not escape the string. Then we should be able to output formatted strings from blocks, I believe. Need to do some testing first, but I think it should work...

EDIT: I also just realized that your command string is probably wrong. ./~/ is weird. Also, you said your program is in ~/home/test/Desktop/programming/bar/target/debug/bar, but you the path you put in the config is ./~/Desktop/programming/bar/debug/bar. Just try launching the program from your command line while being in your home directory. The way you can start it from there should also work for succade.

@Joe23232
Copy link

Joe23232 commented Jul 8, 2020

The reason it doesn't work is probably because succade does not expect to get lemonbar-style format strings from your script. So if your program outputs something like %{B#665544}foo bar%{B-}, then succade will escape the % characters.

Oh I see, interesting I guess I do need to escape the characters.

Is that what is happening or what do you mean by "it is not working"?

Nothing outputs at all from my script. If I run by typing ./bar then it works. But to output it to succade it doesn't seem to do anything. In the command part, is my syntax correct to run the script?

If my assumption is correct, then I could probably implement a new option, let's call it raw, that tells succade to not escape the string. Then we should be able to output formatted strings from blocks, I believe. Need to do some testing first, but I think it should work...

Oh cool, let me know when it comes out. I was thinking if I can get my code to work 100% correctly would you want to put it into your repo?

EDIT: I also just realized that your command string is probably wrong. ./~/ is weird. Also, you said your program is in /home/test/Desktop/programming/bar/target/debug/bar, but you the path you put in the config is .//Desktop/programming/bar/debug/bar. Just try launching the program from your command line while being in your home directory. The way you can start it from there should also work for succade.

Yeah I thought I got the syntax wrong. The executable is located in ~/Desktop/programming/bar/debug/bar. How would I get succade to explicitly use the specified directory of where my executable is located?

@domsson
Copy link
Author

domsson commented Jul 8, 2020

I was thinking if I can get my code to work 100% correctly would you want to put it into your repo?

If your program complies with the design principles outlined in the candies repo, then I'd be happy to add it. Otherwise, you could create a repo yourself and I can add it to my fetch-all-the-things list.

Yeah I thought I got the syntax wrong. The executable is located in ~/Desktop/programming/bar/debug/bar. How would I get succade to explicitly use the specified directory of where my executable is located?

If you open a new terminal, type ~/Desktop/programming/bar/debug/bar and your program starts, then the same command should work from within succade. What does your program output? Does your program print to stdout and adds a newline (\n) at the end?

@domsson
Copy link
Author

domsson commented Jul 8, 2020

@Joe23232 I just implemented and pushed the raw option (see this issue for details). If you pull and build the latest version of succade, you should now be able to do something like this:

[foo]
command = "echo '%{B#FF0000}red foo%{B-}'"
raw = true

Let me know how that goes. :)

@Joe23232
Copy link

Joe23232 commented Jul 8, 2020

If your program complies with the design principles outlined in the candies repo, then I'd be happy to add it. Otherwise, you could create a repo yourself and I can add it to my fetch-all-the-things list.

Ah I see cool :)

@Joe23232 I just implemented and pushed the raw option (see this issue for details). If you pull and build the latest version of succade, you should now be able to do something like this:

Let me try
So when building it I get this warning and error message.

In function ‘barstr’,
    inlined from ‘feed_lemon’ at src/succade.c:879:16,
    inlined from ‘main’ at src/succade.c:1315:3:
src/succade.c:472:13: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  472 |  bar_str[0] = '\0';
      |  ~~~~~~~~~~~^~~~~~
src/succade.c: In function ‘main’:
src/succade.c:471:18: note: at offset 0 to an object with size 0 allocated by ‘malloc’ here
  471 |  char *bar_str = malloc(bar_str_len);
      |                  ^~~~~~~~~~~~~~~~~~~
/usr/bin/ld: cannot find -linih
collect2: error: ld returned 1 exit status

Did it actually completely fail to build?

@domsson
Copy link
Author

domsson commented Jul 8, 2020

Same "errors" as the first time around, which can be ignored for now, plus one more, which comes from the fact that you ran ./build instead of ./build-inih. Try that and it should work fine. :)

@Joe23232
Copy link

Joe23232 commented Jul 8, 2020

Same "errors" as the first time around, which can be ignored for now, plus one more, which comes from the fact that you ran ./build instead of ./build-inih. Try that and it should work fine. :)

Oh lol I forgot thanks for pointing that out :)

@Joe23232
Copy link

Joe23232 commented Jul 8, 2020

Yes it works very well even with the Rust script, thanks mate I hope to make something awesome out of it :)

@domsson
Copy link
Author

domsson commented Jul 8, 2020

Great! I can't wait to see your first results. And as you've witnessed today, you've already "contributed" a new feature to the project - without any programming. :)

@Joe23232
Copy link

Joe23232 commented Jul 9, 2020

Cool mate :) Glad I could help you out with your project. I will keep you posted once when it is ready. For now it is only going to support spectrwm but I plan to in the future make my code support for other WMs as well.


In regards to the powerline font https://github.com/ryanoasis/powerline-extra-symbols how would I install it if you happen to know?


command = "echo '%{B#FF0000}red foo%{B-}'" In this code, what does %{B-} even mean?

@domsson
Copy link
Author

domsson commented Jul 9, 2020

In the bar section, you can set default foreground and background colors. These will apply to everything on the bar, unless a different color is being specified for a block, label or affix. When you use format strings manually, you can refer to the Lemonbar README for how they work. In this example, %{B#FF0000} sets the background color to red. %{B-} sets it back to the default. If you didn't put the %{B-}, then everything that came after this block would also be red. Consider it as tidying up after yourself. The same goes for %{F-}. In case you know HTML or XML, think of this as the closing tag.

For installing fonts, you'll have to search online for something like "how to install opentype fonts in (name of your distro)".

Also, if your Rust workspace program is on GitHub / GitLab, feel free to link it.

@Joe23232
Copy link

Joe23232 commented Jul 9, 2020

Ah that makes sense :)

Do you know how would I install powerline fonts, I am sorry to ask you for this I am struggling to find out how to build it that is all :)

@domsson
Copy link
Author

domsson commented Jul 9, 2020

Download the .otf file (that's the font), then install it according to how it works in your distro. Here is the first result I found for Arch, here is the first result I found for Ubuntu. Here is a result for general "Linux". Just use your search-engine-foo. The Internet would know better than me. ;)

@Joe23232
Copy link

Joe23232 commented Jul 9, 2020

Thanks mate :)

@Joe23232
Copy link

Joe23232 commented Jul 9, 2020

I know this is off topic but just out of curiosity, how come you have written all the projects inside candies in C rather than C++?

@domsson
Copy link
Author

domsson commented Jul 9, 2020

I started programming in PHP (self-taught), then used Java for a long time (that's what they taught us in University). After University, I wanted to learn C++ because it seems to be the most prevalent language in game programming. However, I had difficulties learning the language, as it has become very complex over the years. A friend of mine suggested we should try programming in C, as it is very low level and therefore would, in a way, teach us much more about the basics of programming than the higher level languages. So I started a couple hobby projects (one of them being succade!) to give C a try. I came to really love C, plus I realized that C seems to be the most prevalent language in the Linux / Kernel world. So... yeah, I guess I like that C is low level and minimalist. :)

@Joe23232
Copy link

Joe23232 commented Jul 9, 2020

Ah I see mate :)

What are your thoughts on Rust? You know the code that I pasted (let me give you an updated version):

use std::process::Command;

fn main()
{
    let workspaces = ["Out1", "Out2"];
    // Initialize variables
    let color = Color
    {
        blue:   0x3b47f7,
        green:  0x14a03e,
        yellow: 0xc6e035,
        red:    0xdd382c,
    };

    let mut output = Command::new("sh");
    output.arg("-c").arg(format!("echo '%{{{}#{:x}}}Out1' '%{{{}#{:x}}}Out2'", is_active(), color.red, is_active(), color.green));
    output.status().expect("Error!");
}

fn output_workspaces()
{

}

fn is_active() -> &'static str
{
    return "F";
}

struct Color
{
    blue: u32,
    green: u32,
    yellow: u32,
    red: u32,
}

What are your thoughts on the Rust programming language? Is this a language better than C or the other way around?

@domsson
Copy link
Author

domsson commented Jul 9, 2020

I don't know Rust, so I can't say. But I remember having seen some benchmarks that showed that Rust has very good performance, similar to C/C++. Seeing how it is a compiled and object-oriented language, I guess it is rather a competitor to C++ than C? But at the end of the day, I don't think one is "better" than the other. I currently enjoy C, so I mostly use C. Others enjoy Rust, so they use Rust. As long as the results are somewhat similar, it doesn't matter.

Use whatever tool works and is right for the job. I remember that the author of bspwm said once that if he were to rewrite (or enhance?) bspwm, he would probably do so in Rust.

EDIT: If this benchmark is worth something, then Rust may even be faster than C for some tasks. Wow!

@Joe23232
Copy link

Joe23232 commented Jul 9, 2020

Ah I see, thanks mate.

I just want to see what is the eqivilant of:

let mut output = Command::new("sh");
output.arg("-c").arg(format!("echo '%{{{}#{:x}}}Out1' '%{{{}#{:x}}}Out2'", is_active(), color.red, is_active(), color.green));
 output.status().expect("Error!");

if it were to be written in C, would it be less complex or more complex? All this code does is it outputs some values onto lemonbar (succade connects this code) (is_active() is a function that I created)?

@domsson
Copy link
Author

domsson commented Jul 9, 2020

Again, I don't know Rust, hence I'm not sure what's happening there. But I assume you're looking at something like printf() or fprintf():

 fprintf(stdout, "%s world!\n", "Hello");

@Joe23232
Copy link

Joe23232 commented Jul 9, 2020

echo '%{B#FF0000}red foo%{B-}' If I wanted to output this exact same command but I don't want to write in shell script, I want to write it in C lang instead, what would be the syntax/command? Sorry for asking so much I am curious to know what would be the most simplest language to use for such a task so I am curious to know its syntax.

@domsson
Copy link
Author

domsson commented Jul 9, 2020

Printing a string to stdout should be similarly simple / performant in pretty much every language under the sun. :) So I wouldn't worry about it. It's the stuff you do to fetch information, like the workspaces, or temperatures, or workload, or whatever, where languages might be different in how easy/hard efficient/inefficient it is. Here is what printing your example string might look like in C:

char color[] = "#FF0000";
char output[] = "red foo";
printf("%%{B%s}%s%%{B-}\n", color, output);

Or, if the "red foo" and color never change, then just:

printf("%%{B#FF0000}red foo%%{B-}\n");

@Joe23232
Copy link

Joe23232 commented Jul 9, 2020

Interesting! However why would you declare color[] as a char, wouldn't it make more sense to declare it as an unsigned 4 byte integer?

@domsson
Copy link
Author

domsson commented Jul 9, 2020

Well, it really depends on the context. But let's say color was an int, then you could probably (I have not tested it) do this:

printf("%%{B#%08X}%s%%{B-}\n", color, output);

@Joe23232
Copy link

Joe23232 commented Jul 9, 2020

Oh I see mate thanks.

@Joe23232
Copy link

Joe23232 commented Jul 9, 2020

Have you used wmctrl package before? I am trying to get the output of the workspace's name but that seems to fail so I was just curious you have some experience with it by any chance?

@domsson
Copy link
Author

domsson commented Jul 9, 2020

I didn't even know about it, but it sounds very useful.

@Joe23232
Copy link

Joe23232 commented Jul 9, 2020

Yeah I was recommended to use it, but yeah I can't get the current work space's name (I can get hte ID).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment