How to change color AND width of non overlay scrollbars in Ubuntu 12.04

125

Solution 1

Note:

The formattings in this answer are optimal for precise (Ubuntu 12.04) only, see next answer for improved formattings for trusty (Ubuntu 14.04).


Make scrollbars visible (change color)

Based on vasa1's informations provided above I changed the color of the classic scrollbars to the default selection color - the same that overlay scrollbars are using as well.

For GTK 3 applications modify:

gksu gedit /usr/share/themes/Ambiance/gtk-3.0/gtk-widgets.css

starting from line 1580 so that it looks like:

.scrollbar.slider,
.scrollbar.slider:hover,
.scrollbar.button,
.scrollbar.slider.vertical,
.scrollbar.button.vertical {
    background-image: -gtk-gradient (linear, left top, right top,
                                     from (shade (@selected_bg_color, 1.38)),
                                     to (shade (@selected_bg_color, 1.22)));
    border-style: solid;
    border-width: 1px;

    -unico-border-gradient: -gtk-gradient (linear, left top, right top,
                                           from (shade (@selected_bg_color, 1.14)),
                                           to (shade (@selected_bg_color, 1.14)));
    -unico-centroid-texture:  url("assets/scrollbar_handle_vertical.png");
    -unico-inner-stroke-gradient: -gtk-gradient (linear, left top, right top,
                                                 from (shade (@selected_bg_color, 1.46)),
                                                 to (shade (@selected_bg_color, 1.3)));
    -unico-inner-stroke-width: 1px;
}

.scrollbar.slider.vertical:hover {
    background-image: -gtk-gradient (linear, left top, right top,
                                     from (shade (@selected_bg_color, 1.28)),
                                     to (shade (@selected_bg_color, 1.02)));
    border-style: solid;
    border-width: 1px;

    -unico-border-gradient: -gtk-gradient (linear, left top, right top,
                                           from (shade (@selected_bg_color, 0.94)),
                                           to (shade (@selected_bg_color, 0.94)));
    -unico-centroid-texture:  url("assets/scrollbar_handle_vertical.png");
    -unico-inner-stroke-gradient: -gtk-gradient (linear, left top, right top,
                                                 from (shade (@selected_bg_color, 1.36)),
                                                 to (shade (@selected_bg_color, 1.1)));
    -unico-inner-stroke-width: 1px;
}

.scrollbar.slider.horizontal,
.scrollbar.button.horizontal {                                   
    background-image: -gtk-gradient (linear, left top, left bottom,
                                     from (shade (@selected_bg_color, 1.38)),
                                     to (shade (@selected_bg_color, 1.22)));

    -unico-border-gradient: -gtk-gradient (linear, left top, left bottom,
                                           from (shade (@selected_bg_color, 1.14)),
                                           to (shade (@selected_bg_color, 1.14)));
    -unico-centroid-texture:  url("assets/scrollbar_handle.png");
    -unico-inner-stroke-gradient: -gtk-gradient (linear, left top, left bottom,
                                                 from (shade (@selected_bg_color, 1.46)),
                                                 to (shade (@selected_bg_color, 1.3)));
}

.scrollbar.slider.horizontal:hover {
    background-image: -gtk-gradient (linear, left top, left bottom,
                                     from (shade (@selected_bg_color, 1.28)),
                                     to (shade (@selected_bg_color, 1.02)));

    -unico-border-gradient: -gtk-gradient (linear, left top, left bottom,
                                           from (shade (@selected_bg_color, 0.94)),
                                           to (shade (@selected_bg_color, 0.94)));
    -unico-centroid-texture:  url("assets/scrollbar_handle.png");
    -unico-inner-stroke-gradient: -gtk-gradient (linear, left top, left bottom,
                                                 from (shade (@selected_bg_color, 1.36)),
                                                 to (shade (@selected_bg_color, 1.1)));
}


.scrollbar.button,
.scrollbar.button:insensitive {
    -unico-outer-stroke-width: 0;
}

This should be default.

For GTK 2 applications modify:

gksu gedit /usr/share/themes/Ambiance/gtk-2.0/gtkrc

starting from line 223 so that it looks like:

style "scrollbar" = "button" {
    xthickness = 2
    ythickness = 2

    bg[NORMAL] = shade(1.3, @selected_bg_color)
    bg[PRELIGHT] = shade (1.04, @selected_bg_color)

    bg[ACTIVE] = shade (0.96, @selected_bg_color)

    engine "murrine"
    {
        border_shades = {1.15, 1.1}
        roundness = 20
        contrast = 1.0
        trough_shades = {0.92, 0.98}
        lightborder_shade = 1.3
        glowstyle = 5
        glow_shade = 1.02
        gradient_shades = {1.2, 1.0, 1.0, 0.86}
        trough_border_shades = {0.9, 0.98}
    }
}

It does not look 100% identical to the GTK 3 formatting, so feel free to improve it.


Make scrollbars clickable (increase width)

To increase the silly small width that were never meant for being used in production, I assume, make the following changes to the same files.

For GTK 3 applications:

gksu gedit /usr/share/themes/Ambiance/gtk-3.0/gtk-widgets.css

modify line 1550 so that it looks like:

.scrollbar {
    -GtkScrollbar-has-backward-stepper: 0;
    -GtkScrollbar-has-forward-stepper: 0;
    -GtkRange-slider-width: 16;

    border-radius: 20px;

    -unico-border-gradient: -gtk-gradient (linear, left top, left bottom,
                                           from (shade (@bg_color, 0.74)),
                                           to (shade (@bg_color, 0.74)));
}

For GTK 2 applications modify:

gksu gedit /usr/share/themes/Ambiance/gtk-2.0/gtkrc

modify line 34 so that it looks like:

GtkScrollbar::slider-width = 16

For those preferring the complete files already edited, you can download mine from here:

GTK 3: gtk-widgets.css

GTK 2: gtkrc

Be careful. Make backups.

Enjoy! :)

Solution 2

I'm assuming you are referring to the overlay scrollbars because you mention Unity. I don't know how to change the width but you can certainly change the color. If the color is distinct enough, I feel the width isn't that much of a problem because on hover it becomes decently wide.

You need to look in your theme's folder for files called gtkrc (in the gtk-2.0 folder) and gtk-widgets.css (in the gtk-3.0 folder). Open these files with a text editor. You may need to use gksudo gedit instead of just gedit if your theme is in /usr/share/themes and not in ~/.themes. Then, search for overlay scrollbars or overlay-scrollbar or something similar and play with the colors specified in those sections. You can even specify your own color in hex code.

Obviously, you can set different colors in the two files if you so choose.

To visualize the changes you may need to switch to another theme and back after you've made and saved the changes to these files.

The changes you make in /usr/share/themes will be system-wide and changes in ~/.themes will be user-specific.

This is what my overlay scrollbar looks like in PCManFM.

My overlay scrollbar

Edit: In case, one is using conventional scrollbars, then to increase the contrast between the slider and trough in gtk-3.0 apps such as gedit, one can edit the gtk-widgets.css file mentioned above. To do so, search for the section titled scrollbar (or something similar) and look for the lines that have something like this:

.scrollbar.slider,
.scrollbar.slider:hover,
.scrollbar.button,
.scrollbar.slider.vertical,
.scrollbar.slider.vertical:hover,
.scrollbar.button.vertical {
    background-image: -gtk-gradient (linear, left top, right top,
                                 from (shade (@bg_color, 1.08)),
                                 to (shade (@bg_color, 0.92)));
    border-style: solid;
    border-width: 1px;

In here, one can play with the values for the background-image by changing the shade. A higher value is brighter, a lower value is darker.

I prefer to do something more simple: I change background-image to background-color and just have a color I like. So, for example, background-color: red; would probably give outstanding contrast.

My code looks like this:

.scrollbar.slider,
.scrollbar.button,
.scrollbar.slider.vertical,
.scrollbar.button.vertical {
    background-color: #003263; /*@theme_bg_color;*/
    /**/
    /**/

Obviously, a backup before editing is advisable and one can comment out stuff in the gtk-widgets.css file instead of deleting things by using /* and */.

(I can't get the formatting of block quotes to work while posting answers. If somebody would clean things up, I'd be grateful.)

One last edit (I hope): Users of Chrome or Chromium may increase contrast by editing their gtk-2.0/apps/chromium.rc file if their theme provides it or by editing gtk-2.0/gtkrc if what is required is present there. In both cases one should search for a section headed style "chrome-gtk-frame". In here, again, play with the shade value in this (or similar) line:

ChromeGtkFrame::scrollbar-slider-normal-color = shade (1.4, @panel_bg)

Or one can simply specific a color like this:

ChromeGtkFrame::scrollbar-slider-normal-color = "#003263"

or

ChromeGtkFrame::scrollbar-slider-normal-color = "blue"

(The quotes are required.)

Solution 3

For Ubuntu 14.04 (Trusty Tahr) slightly different modifications are needed.

GTK 3: gtk-widgets.css goes to: /usr/share/themes/Ambiance/gtk-3.0/gtk-widgets.css

GTK 2: gtkrc goes to: /usr/share/themes/Ambiance/gtk-2.0/gtkrc

Make backups prior:

sudo cp /usr/share/themes/Ambiance/gtk-2.0/gtkrc /usr/share/themes/Ambiance/gtk-2.0/gtkrc.bak
sudo cp gtkrc /usr/share/themes/Ambiance/gtk-2.0/
sudo cp /usr/share/themes/Ambiance/gtk-3.0/gtk-widgets.css /usr/share/themes/Ambiance/gtk-3.0/gtk-widgets.css.bak
sudo cp gtk-widgets.css /usr/share/themes/Ambiance/gtk-3.0/ 

Those commands expects the downloaded files gtkrc and gtk-widgets.css in the current directory.

Share:
125

Related videos on Youtube

Ajit
Author by

Ajit

Updated on September 18, 2022

Comments

  • Ajit
    Ajit over 1 year

    I am currently working on a program to traverse through a list of numbers with two different functions to find the sum and a specific value. Here is the code that I have implemented

    class Program
    {
        static int i, sum;
        static List<int> store = new List<int>();
    
        static void Main(string[] args)
        {
    
    
            for (i = 0; i < 100; i++)
            {
                store.Add(i);
            }
    
            i = 0;
            TraverseList();
            Console.ReadLine();
        }
    
        static void TraverseList()
        {
            while (i < store.Count)
            {
                FindValue();
                FindSum();
                i++;
            }
    
            Console.WriteLine("The sum is {0}", sum);
        }
    
        static void FindValue()
        {           
            if (store[i] == 40)
            {
                Console.WriteLine("Value is 40");
            }                
        }
    
        static void FindSum()
        {
            sum = sum + store[i];
        }
    }
    

    I was thinking of separating FindSum and FindValue into two different functions and not calling them in TraverseList. Is there any other way of doing it rather the duplicating the common code of list traversal in those two functions as I have done here

    class Program
    {
        static int i, sum;
        static List<int> store = new List<int>();
    
        static void Main(string[] args)
        {
    
    
            for (i = 0; i < 100; i++)
            {
                store.Add(i);
            }
    
            i = 0;
            FindValue();
            i = 0;
            FindSum();
    
            Console.ReadLine();
        }
    
        static void FindValue()
        {
            while (i < store.Count)
            {
                if (store[i] == 40)
                {
                    Console.WriteLine("Value is 40");
                }
                i++;
            }
        }
    
        static void FindSum()
        {
            while (i < store.Count)
            {
                sum = sum + store[i];
                i++;
            }
    
            Console.WriteLine("The sum is {0}", sum);
        }
    }
    
    • Uri Herrera
      Uri Herrera over 11 years
      Screenshot would be nice.
    • Anwar
      Anwar over 11 years
      A screenshot is a must I think in this case. Since the provided answer isn't what you wanted.
    • IKKA
      IKKA over 11 years
      Hi @UriHerrera and Anwar, I already added some images. Thanks!
    • Jon
      Jon over 10 years
      This code is extremely bad, the most blatant offense being that your methods FindValue and FindSum use hidden parameters (store and i) for no reason. There is absolutely no need to do things this way. Throw this code away and start again.
    • Ajit
      Ajit over 10 years
      @jon I am a beginner and I have been trying to get things working and I don't even know what hidden parameters are. I will surely do a bit of research on that.
    • Jon
      Jon over 10 years
      @AjitPeter: I am just trying to say that you have taken the wrong path here. "Hidden parameters" means that your functions need some things to work with, but that's not mirrored by their signatures (they look like they need no arguments at all). Don't ever do that. In this case, both should accept one argument and you should pass store[i] as a parameter.
    • neuronet
      neuronet over 7 years
      Please for the love of god why won't the devs just make this easy to change under system settings?
  • IKKA
    IKKA over 11 years
    I'm sorry, @vasa1! I forgot to mention that I removed the overlay scrollbars using "Unsettings" or some commands. Now I have narrow and low-contrast scrollbars. That's what I need to fix. (I already edited the original question).
  • Admin
    Admin over 11 years
    @Chuqui, could you please mention a few specific apps which are problematic? And do mention which theme you are using. I know of at least one theme that has very thin scrollbars. In that case, it may just be a matter of trying another theme.
  • IKKA
    IKKA over 11 years
    Hi @vasa1, I want to thank you again for the detailed instructions you gave me. I'm sorry I wasn't clear enough in my question. Above you can see images of applications where the scrollbars are hard to see: Nautilus, Nuvola Player and Ubuntu Software Center. On the contrary, using Gnome Color Chooser I could change Firefox, Ubuntu One and other software's scrollbars, like LibreOffice. I'm using the default theme: Ambiance
  • Nicolas
    Nicolas almost 11 years
    For those that already read my answer: with last edit I improved the formatting largely. :)
  • Ajit
    Ajit over 10 years
    @SriramSakthivel I haven't used linq before and dont have much about it
  • Sriram Sakthivel
    Sriram Sakthivel over 10 years
    FindAll? use Find or Exist or Any(Linq) methods
  • Yosi Dahari
    Yosi Dahari over 10 years
    @SriramSakthivel - No. It seems like he wants all items, look at his code, he doesn't stop iterating after finding first item.
  • Yosi Dahari
    Yosi Dahari over 10 years
    Don't call lambda expression parameter i - I think that's a bad practice. The OP doesn't want Any item.
  • Ajit
    Ajit over 10 years
    FindSum() is only an example of the functionality that I am looking to achieve. So the sum() wouldn't help me. My concern is that if I were to add more functions to manipulate the list I would end up duplicating the list traversal for each function similar to FindSum() or FindValue().
  • Ajit
    Ajit over 10 years
    I guess the linq implementation above will help me only this particular case but my concern is of duplicating the same code (list traversal) for any further functions that I add in the future.
  • Yosi Dahari
    Yosi Dahari over 10 years
    @AjitPeter - YES this specific code will help you now, but if you learn some more about Linq, you can solve much more complicated problems, and then, the so called duplicated code will be in the Linq code and not yours.
  • Ajit
    Ajit over 10 years
    Linq is really helpful with predefined functions like sum() available already
  • Ajit
    Ajit over 10 years
    I agree that the code here is bad even for the standards an example :) The above example is just an overview of the functionality that I am trying to achieve. The traversal list is not just a single line of code. I have around 50 lines of code and 3 functions which all use the traversal function. I thought there might be a better way of doing it rather copying the same 50 lines of code 3 times for each function.
  • Chris
    Chris over 10 years
    In that case, have one loop, and then pass the list + the index to your different methods. I just wanted to stress that even for an example, never ever reuse i as you have done, it's bad for you!
  • Ajit
    Ajit over 10 years
    Is any other way of doing it of which I am unaware of since I am a beginner. I was of the notion that code duplication is not good. Some of the comments earlier said the same that it is alright to have duplicate code.
  • Chris
    Chris over 10 years
    Yeah they're right - if you find yourself rewriting the same lines of code all over the place, those lines of code should probably be moved into a method. But don't take it all too far. A single line, something as common as a for/foreach loop, is nothing to worry about.
  • Ajit
    Ajit over 10 years
    Don't think the passing the index would work as I have to traverse through the entire list always for all the three methods.
  • Chris
    Chris over 10 years
    Yeah that was if you really wanted the loop outside those methods. It would also complicate other things. So I'd say just have a loop in each of your methods.
  • Ajit
    Ajit over 10 years
    I did move the traversal part to a single method. That's what I have in the very first part of the code. But that results in all the three methods in Traverse() function restricting me to call all the 3 functions together. I would have to comment out the other two if I have to call only one function, which is what I am doing at the moment.
  • Ajit
    Ajit over 10 years
    I dont think commenting out other functions to call only one function is a good programming practice :)
  • Chris
    Chris over 10 years
    Yeah another reason for having the loop inside each method then!
  • Ajit
    Ajit over 10 years
    So I guess there is no other better way of doing it and I will have to stick to what I am doing now. I wonder what @jon skeet's answer to this would be.
  • Trevor Elliott
    Trevor Elliott over 10 years
    @AjitPeter You would have to be more specific about exactly what you are looking to achieve for advice on how to achieve it. There are a limitless amount of things you could do with a list and a large number of ways to solve each. It sounds like you're worried about duplicating the iteration code. This is literally only one line of code if you use a simple for or foreach loop. The only way you can condense it further is to use syntactic sugar like the LINQ statements I've shown you. Chances are you can use it to solve 95% of your problems.
  • Ajit
    Ajit over 10 years
    Please refer to my chat with @chris where I have mentioned what I am trying to achieve and why I am trying to separate the functions which use the common traverse()
  • Trevor Elliott
    Trevor Elliott over 10 years
    It doesn't sound like you have a real world problem. You want to have a large number of different kinds of operations you could perform on a list and you want an easy way to pick and choose which operations to execute. It sounds like a ridiculous scenario where you might have 30 functions and you want to decide "only run these 23 functions". Stackoverflow isn't really for questions about what if you wanted to do something silly. See the help page. Unless you can provide an actual real world problem you need solving we aren't much help to you.
  • Ajit
    Ajit over 10 years
    I fail to understand why it is not a real world problem. So you are saying that if I have a set of 30 functions which all need to traverse through the list the only way possible is to duplicating the code in each and every function that uses it. That itself is a problem with the traversal code having to be same across all the 30. I don't think you have understood the actual problem.
  • bastijn
    bastijn over 10 years
    His answer would probably to buy a book on programming principles :). There are many good lists floating on SO. You can learn yourself how to be a programmer / coder/ developer, that is true. Yet you cannot do so without the proper learning objects such as books (examples, test projects, courses, guides, blogs, and so on). I don't want to scare you; Welcome to the world of programmers / developers! Just please, start in a proper way. In the end, it is going to save you a lot of time, and you will actually be able to finish larger projects :).
  • Trevor Elliott
    Trevor Elliott over 10 years
    It's not realistic because not all functions are equal. The order they are called in can matter. They can modify the data before the next function modifies it further. You could be filtering a subset of your list and only modifying that subset in further functions. Some functions return a result that might not be a list, such as summing the elements of a list and then doing something with the sum. So you can't just say "I have a set of 30 functions". That's not realistic. Programming is based on problems, not functions. Functions are a solution to problems, not the problem itself
  • Ajit
    Ajit over 10 years
    I am talking of functions which operates on the list in the exact way as the two shown in example. In my case the traversal through the list is the common part and it doesn't not modify the list in any way. Say I need to add two separate functions in my code to find the total even numbers and odd numbers respectively, I don't think implementing two separate functions with the same list traversal is an ideal solution as I am duplicating it for each and every function that uses it.
  • Pavel V.
    Pavel V. over 9 years
    Wouldn't this be better as an edit to your other answer?
  • Nicolas
    Nicolas about 9 years
    My intention for a separate answer was to clearly separate 12.04 stuff from 14.04 so that consumers of my prepared layout files are able to find the right ones quickly and without being confused. But ... well ... one can argue about ... ;)