Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 100 additions & 16 deletions xborders
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import subprocess
import sys
import threading
import webbrowser
import colorsys

import cairo
import gi
Expand All @@ -28,24 +29,60 @@ BORDER_R = 123
BORDER_G = 88
BORDER_B = 220
BORDER_A = 1
BORDER_GRADIENT_COLORS = []
ABSOLUTE_GRADIENT = None
NO_VERSION_NOTIFY = False
OFFSETS = [0, 0, 0, 0]


def set_border_rgba(args):
try:
literal_value = int(args.border_rgba.replace("#", "0x"), 16)
except:
print(
f"`{args.border_rgba}` is an invalid hexadecimal number!",
file=sys.stderr,
)
sys.exit(1)
args.border_red = literal_value >> (3 * 8) & 0xFF
args.border_green = literal_value >> (2 * 8) & 0xFF
args.border_blue = literal_value >> (1 * 8) & 0xFF
args.border_alpha = (literal_value >> (0 * 8) & 0xFF) / 255 # map from 0 to 1

global BORDER_GRADIENT_COLORS, ABSOLUTE_GRADIENT

if args.border_rgba: # solid color
try:
literal_value = int(args.border_rgba.replace("#", "0x"), 16)
except:
print(
f"`{args.border_rgba}` is an invalid hexadecimal number!",
file=sys.stderr,
)
sys.exit(1)
args.border_red = literal_value >> (3 * 8) & 0xFF
args.border_green = literal_value >> (2 * 8) & 0xFF
args.border_blue = literal_value >> (1 * 8) & 0xFF
args.border_alpha = (literal_value >> (0 * 8) & 0xFF) / 255 # map from 0 to 1

elif args.border_gradient: # gradient

for color in args.border_gradient:
try:
literal_value = int(color.replace("#", "0x"), 16)
except:
print(
f"`{args.border_rgba}` is an invalid hexadecimal number!",
file=sys.stderr,
)
sys.exit(1)

red = (literal_value >> (3 * 8) & 0xFF) / 255
green = (literal_value >> (2 * 8) & 0xFF) / 255
blue = (literal_value >> (1 * 8) & 0xFF) / 255
alpha = (literal_value >> (0 * 8) & 0xFF) / 255

BORDER_GRADIENT_COLORS.append((red, green, blue, alpha))

elif args.rainbow: # rainbow

for i in range(args.rainbow_steps):
color = colorsys.hsv_to_rgb(i / args.rainbow_steps, args.rainbow_saturation, args.rainbow_value)

BORDER_GRADIENT_COLORS.append((*color, 1))

# generate absolute gradient
if args.absolute_gradient:
ABSOLUTE_GRADIENT = cairo.LinearGradient(0, 0, *get_screen_size(Gdk.Display.get_default()))
for i, color in enumerate(BORDER_GRADIENT_COLORS):
ABSOLUTE_GRADIENT.add_color_stop_rgba(i / len(BORDER_GRADIENT_COLORS), *color)

def get_version():
our_location = os.path.dirname(os.path.abspath(__file__))
Expand Down Expand Up @@ -100,11 +137,46 @@ def get_args():
default=1,
help="The border's alpha value, between zero and 1",
)
parser.add_argument(
color_group = parser.add_mutually_exclusive_group()
color_group.add_argument(
"--border-rgba",
default=None,
help="The colours of the border in hex format, example: #FF0000FF",
)
color_group.add_argument(
"--border-gradient",
default=None,
help="The colors of the border as a gradient, separated by spaces. Example: #FF0000FF #00FF00FF",
nargs="+",
)
parser.add_argument(
"--absolute-gradient",
action="store_true",
help="Use one gradient over the entire screen, and mask the borders to it",
)
color_group.add_argument(
"--rainbow",
action="store_true",
help="Use a rainbow gradient for the color of the border.",
)
parser.add_argument(
"--rainbow-steps",
type=int,
default=20,
help="The amount of colors in the rainbow gradient",
)
parser.add_argument(
"--rainbow-saturation",
type=float,
default=1,
help="The saturation of the colors when using --rainbow, on a scale from 0 to 1."
)
parser.add_argument(
"--rainbow-value",
type=float,
default=1,
help="The value (brightness) of the colors when using --rainbow, on a scale from 0 to 1."
)
parser.add_argument(
"--border-mode",
type=str,
Expand Down Expand Up @@ -149,7 +221,7 @@ def get_args():
if args.version is True:
print(f"xborders v{get_version()}")
exit(0)
if args.border_rgba is not None:
if args.border_rgba is not None or args.border_gradient is not None or args.rainbow is not None:
set_border_rgba(args)

# Extract the literal values
Expand Down Expand Up @@ -432,7 +504,19 @@ class Highlight(Gtk.Window):
else:
ctx.rectangle(x, y, w, h)

ctx.set_source_rgba(BORDER_R / 255, BORDER_G / 255, BORDER_B / 255, BORDER_A)
if BORDER_GRADIENT_COLORS:

if ABSOLUTE_GRADIENT:
ctx.set_source(ABSOLUTE_GRADIENT)
else:
grad = cairo.LinearGradient(x, y, x + w, y + h)
for i, color in enumerate(BORDER_GRADIENT_COLORS):
grad.add_color_stop_rgba(i / len(BORDER_GRADIENT_COLORS), *color)
ctx.set_source(grad)

else:
ctx.set_source_rgba(BORDER_R / 255, BORDER_G / 255, BORDER_B / 255, BORDER_A)

ctx.set_line_width(BORDER_WIDTH)
ctx.stroke()
ctx.restore()
Expand Down