Currently I use
import XMonad.Layout.NoBorders
...
xmonad $ defaultConfig { layoutHook = noBorders $ layoutHook defaultConfig }
but this makes noBorder all the layouts, not just "Full".
I know, that I can simply copy layoutHook definition from default config and add noBorder before "Full", but I want the beautiful way, hope Haskell provides some means for it.
Instead of using noBorders, you could use smartBorders, which hides the border when there's only one window (or a floated window covers the entire screen). That isn't quite the same thing as only hiding it with the Full layout, but it might be close enough for your purposes.
Failing that, the best option is probably to copy the default layoutHook. It's not very big, and you're quite likely to want to customise it in the future, anyway. You might be able to write a typeclass with instances for all the standard LayoutClasses that applies noBorders to Full, but it'd be uglier than simply copying the default layoutHook.
Related
The Goal
Set no border for specific windows in Xmonad.
Concrete example: I'd like firefox and feh always have no border. I want to set this not only for specific layout (e.g., single window) or specific window mode like float.
Attempt A
The most straight forward idea I have is to add a line in manageHook, which supposes to handle window creation. So I put a line in my customized ManageHook:
className =? "firefox" --> ask >>= \w -> liftX $ withDisplay $ \d -> io $ setWindowBorderWidth d w 0 >> idHook
It compiles, but unfortunately nothing happens when I start firefox.
Then I try to debug it:
Tested the following and it works (new firefox window is floated), which indicates my customized ManageHook works, and my logic (modify the window followed by idHook) should be OK.
className =? "firefox" --> ask >>= liftX . float >> idHook
Tested setWindowBorderWidth function by trying toggleBorder in XMonad.Actions.NoBorders. toggleBorder does something similarly calling setWindowBorderWidth. I used a key binding to invoke toggleBorder and it works. So setWindowBorderWidth works well during a Xmonad session after the window is created.
Tested the following (found it here) but it doesn't work, same as my code (Attempt A).
className =? "firefox" --> ask >>= liftX . toggleBorder >> idHook
Attempt B
I find the hasBorder function in XMonad.Layout.NoBorders and also this answer, but I did not succeed.
If I only put className =? "firefox" --> hasBorder False in ManageHook but does not use layoutHook, nothing happens. I checked the source code of hasBorder and found it only broadcast a message but not set the border. I think I may need to invoke a layoutHook from XMonad.Layout.NoBorders to really set the border but I am not sure which one I should use. And I am also not sure if I need to specify any layout to use XMonad.Layout.NoBorders.
Questions
Does Xmonad set border after ManageHook so my code in Attempt A is nullified?
If Q1 is true, does it mean I can only set no border at LayoutHook (likely using XMonad.Layout.NoBorders) when the window is drawn on the screen?
If Q2 is true, do I need to specify a layout and which layoutHook I can use?
I'd go with attempt B:
Import the NoBorders module from xmonad-contrib:
import XMonad.Layout.NoBorders
Define your constraints in your manageHook:
className =? "feh" --> hasBorder False
className =? "firefox" --> hasBorder False
And apply one of the module's layout modifiers, e.g. smartBorders to all of your layouts at once:
layoutHook = smartBorders $ Full ||| ResizableTall 1 (3/100) (1/2) [] ||| ...
Note: This will only affect windows created after recompiling and restarting XMonad. Already existing instances of firefox and feh would still have their borders until closed and restarted.
I think I find the answers to my questions.
Does Xmonad set border after ManageHook so my code in Attempt A is nullified?
Yes.
Looks like xmonad window init logic is in XMonad/Operations.hs. When a window is created, the function manage() is called. The last three lines of the function:
load ManageHook,
apply ManageHook with runQuery(),
run the windows() function, which loads border information from config and applies setInitialProperties() function to set borders according to the border config.
The last step setInitialProperties() calls setWindowBorderWidth() with border width loaded from config, which nullifies my setWindowBorderWidth() as a ManageHook step.
If I do not change this logic in XMonad/Operations.hs, it looks like I can only go with Attempt B. However, I really find the windows jumping issue annoying. This does not only occur in Full layout, I am using Tall with a single window. When I switch between two workspaces, both of which have a single window with no border, I see this jumping. The visual effect affects all pixels on screen since it needs to scale the entire window.
If Q1 is true, does it mean I can only set no border at LayoutHook (likely using XMonad.Layout.NoBorders) when the window is drawn on the screen?
No. Another possibility besides LayoutHook is logHook.
If Q2 is true, do I need to specify a layout and which layoutHook I can use?
Yes. However, if logHook is used, there is no need to overwrite the default layouts.
Solution
Let's put up a new XMonad extension to achieve this functionality that people asked 12 years ago.
So I've updated Sublime Text 3 to version 3170 on Ubuntu today and apparently this broke my whitespace coloring - I always have this option set:
draw_white_space": "all"
because I like seeing my spaces and tabs in dark grey - not distracting, but visible enough to be able to see/count them or locate tabs that should be spaces instead.
After the update, the whitespaces are light green, which makes them super distracting. Is there any way to set this back to grey?
One of the features of Stable build 3170 (and many of the Dev builds in this series) is support for invisibles in the tmTheme color scheme as well as in the new sublime-color-scheme format. This is something that existed in tmTheme prior to this, but Sublime did not use the value in that color scheme key and instead used another color.
At the moment it's unclear exactly what color was originally used, but possibly it was the foreground color with an alpha value applied to "dim" it, so the following may require some experimentation to find the right color.
A side effect of this change is that for some color schemes, the color scheme author may have had a value in the invisibles key that was not honoured previously but which now is, which makes things display incorrectly. Or correctly, depending on how you look at it.
You mentioned in comments above that you're using Neon Color Scheme and in that scheme the invisibles value is set to #06FF05 which is indeed a green color.
In order to solve your problem you need to edit the color scheme to apply a different color to that part of the color scheme to get the gray color that you want.
The easiest way to accomplish this would be to take advantage of the addition of the sublime-color-scheme resource type in Sublime Text. Many resource types in Sublime "stack" together at load time to allow for the creation of a partial override.
It turns out that in the case of this particular file format, sublime-color-scheme stacks with tmTheme files of the same base name, since they are represented the same way in memory once they're loaded.
As a result of that, you can adjust the invisibles color by creating a file with the name Neon.sublime-color-scheme in your User package with the following contents:
{
"globals":
{
"invisibles": "#FF00FF"
}
}
The Neon.sublime-color-scheme stacks with the Neon.tmTheme from the package, and since the User package content is always loaded last, this overrides just the invisibles color (in this case to magenta) but leaves the rest of the color scheme untouched.
This of course applies to any color scheme so long as you know the name of the tmTheme file that you're using. The same mechanism can be used to extend your theme to include colors for new scopes or alter the colors of existing scopes without having to recreate a whole new tmTheme or sublime-color-scheme file. See the color scheme documentation for more information.
Doing this creates a partial override, which means that regardless of the content of the underlying color scheme, your changes will still take effect with no overt warning. In this case that's pretty low key as far as potential problems are concerned.
Another way to accomplish this goal is to make changes to the tmTheme file by creating an override. This is marginally more complicated than the above but potentially still useful. For example, this can be used for any package resource of any type in order to modify things to your liking.
In order to create such an override:
Install PackageResourceViewer if you don't already have it installed.
Enter prvo in the command palette and select PackageResourceViewer: Open Resource
Select Neon Color Scheme, then Neon.tmTheme (or the appropriate package and file, depending on what you're doing)
Make appropriate changes to the file as desired and save
This sequence of steps opens the underlying package resource file for you to look at and/or modify. Saving the file creates an override by creating a folder in the Packages folder named for the package and putting the modified file inside. When Sublime loads package resources, the version that's unpacked in the Packages folder takes precedence over the version that's in the package.
In the case of a color scheme tmTheme file, near the top you'll see a settings key, and inside of it, this set of tags sets the color used for invisibles, which you can modify as you see fit.
<key>invisibles</key>
<string>#06FF05</string>
As with any override, once you do this your version of the color scheme (or any other package reaource) will supersede the version that ships with the package, which means that if the package gets updated, your version of the file will still be used without any warnings or messages to tell you that it's happening.
That's probably not a big deal for a color scheme; the OverrideAudit package will warn you if this happens if you're worried. Alternatively, you can make the modifications as above but do a Save As instead of a Save and save the file in your User package, and then alter the color scheme setting to use that version of the color scheme instead.
If you do that and use the same file name, the scheme will appear twice in the color scheme selector; make sure you choose the version that says it's in the User package to be sure you're using your modified version.
Customize your color scheme's whitespace setting:
Sublime Text > Preferences > Customize Color Scheme
{
"globals": {
"invisibles": rgba(255, 255, 255, 0.15)
}
}
No plugins necessary (:
Sublime Theme Customizing Docs here
I'm writing a Haskell program with click-and-drag functionality, so with each mouse movement event an update gets painted to the window. At the moment I'm using
renderWithDrawable myCanvas update
However this is flickering a lot. My understanding is that I need to create a separate drawable (a "surface"?), render to that, and then blit it onto the screen window in a single operation. However I'm confused as to the right way to do this.
I've found drawWindowBeginPaintRegion, which talks about eliminating flicker.
However it is removed in Gtk3 according to the Haddock docs. So I'm not sure if I should use this, as it seems to be deprecated.
I've also found renderWithSimilarSurface in Cairo, which seems to do something similar.
I'm also not sure how these functions relate to renderWithDrawable: do I have to use them inside that function, or what?
What is the right way to do this?
Edit
This seems to be a known thing in Cairo. I'm trying to figure out how to handle this in Haskell.
Explanation and solution in Python
Description of how to handle this issue in raw C
The right way to do this is to make sure all your drawing comes from within expose events, and operates on the draw window provided by the event. You can mark a region as "dirty" and trigger a synthetic expose event using drawWindowInvalidateRect, drawWindowInvalidateRegion, or widgetQueueDraw.
A quick worked example of setting up the drawing pipeline follows. It is excerpted from a custom Viewport type, which does Google-maps style panning with smooth motions on drag-and-release operations, that I built for a side-project some time ago. To support that, it has to redraw on mouse motion events, so it addresses a similar use case to your described problem. I've elided irrelevant stuff with ... to highlight the important bits. I've uploaded the complete project to github just now, so you can browse the repo to see the full details of Viewport. (It's been years though, so there's probably a fair bit of bitrot -- don't expect the project to just build and run with modern GHCs/packages.)
viewportNew :: Viewport -> IO DrawingArea
viewportNew v = do
da <- drawingAreaNew
-- ...
on da exposeEvent $ exposeViewport posRef (draw v)
-- ...
exposeViewport :: IORef Position -> RegionRenderer -> EventM EExpose Bool
exposeViewport posRef draw = do
dw <- eventWindow
region <- eventRegion >>= liftIO . regionGetRectangles
-- ...
liftIO . renderWithDrawable dw $ do
-- Cairo () action goes here
-- can reference region to decide which things to draw
draw region
return True -- see documentation of exposeEvent for what this means
This template should take advantage of gtk's built-in double-buffering and work with both the gtk and gtk3 packages.
I'm building a Container using code and now I want to set the Styleusing one UnselectedStyle from the Resource Editor.
I'm doing this because, I don't find the way to add a LinearBackground color and a RoundBorder to my Container. When I put the two properties to the Style, the background color has gone.
So I finally add this Style using the UIManager.getInstance().addThemeProps(String name ThemeFromResource); and later the setUIID(String nameStyle). Is working fine...my Containergets the Style, but the app lose the navigation, the back Commandhas gone.
How can do this? I would like to do with my first way...creating the lineargradient and the border and adding it to the style, but I don't find the way.
I would strongly suggest against doing that.
Border's override other forms of background, round border tries to respect some of them but is REALLY inefficient about that. It effectively draws the background on a mutable image then draws the round border on another mutable image, gets the RGB for both and performs a NOT operation to crop the background into a round image. This (as you might understand) is REALLY expensive in terms of performance, while the image is then cached it is still expensive in the longer term.
You should use image borders which are MUCH faster.
Is it possible in gtk3 to create a menu that is transparent? The underling window would use an image as it's background.
I can use a color for the window background but not a image.
I attempted to do what you said using an example from the gdk2 reference by adding a background image first and then porting it to gtk3. I'm no expert at gtk at all, but I did make it somehow compile:
http://pastebin.com/0XwUW5k3 (note that there has to be a "background.png" in the same folder)
The transparent dark rectangle holding the widgets is most likely the box; I tried settings its background color to full transparency as well, but it didn't work, and you'd probably have to do the composing/drawing of it yourself if you wanted it to be completely transparent, but that's not something I'd suggest because it seems too complex..
Also, you might want to create a background image with an already fitting resolution for the window, then you could skip the scaling part.
The scale function originally comes from this mailling-list thread