Adds more window title options (#169)
* Adds options for windowtitle to toggle: custom title, icon and truncation * Implements window title toggles: showIcon and showCustomTitle; Adds a new default title function and truncates it if specified * incorporate new show label option into window title * fix window title spacing to work with new styles * allows truncation for custom window titles * allows custom window title icon with default window title * add option to show the window class name or title; refactor for consistency and easier readability * remove redundant custom window title check
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
const hyprland = await Service.import("hyprland");
|
||||
import options from 'options';
|
||||
import { ActiveClient } from 'types/service/hyprland'
|
||||
import Label from "types/widgets/label";
|
||||
|
||||
const filterTitle = (windowtitle: ActiveClient) => {
|
||||
const windowTitleMap = [
|
||||
@@ -127,15 +128,36 @@ const filterTitle = (windowtitle: ActiveClient) => {
|
||||
}
|
||||
|
||||
return {
|
||||
icon: foundMatch ? foundMatch[1] : windowTitleMap[windowTitleMap.length - 1][1],
|
||||
label: foundMatch ? foundMatch[2] : windowTitleMap[windowTitleMap.length - 1][2]
|
||||
icon: foundMatch[1],
|
||||
label: foundMatch[2]
|
||||
};
|
||||
};
|
||||
|
||||
const getTitle = (client: ActiveClient, useCustomTitle: boolean, useClassName: boolean) => {
|
||||
if (useCustomTitle) return filterTitle(client).label;
|
||||
if (useClassName) return client.class;
|
||||
|
||||
let title = client.title;
|
||||
// If the title is empty or only filled with spaces, fallback to the class name
|
||||
if (title.length === 0 || title.match(/^ *$/)) {
|
||||
return client.class;
|
||||
}
|
||||
return title;
|
||||
};
|
||||
|
||||
const truncateTitle = (title: string, max_size: number) => {
|
||||
if (max_size > 0 && title.length > max_size) {
|
||||
return title.substring(0, max_size).trim() + "...";
|
||||
}
|
||||
return title;
|
||||
};
|
||||
|
||||
const ClientTitle = () => {
|
||||
const { custom_title, class_name, label, icon, truncation, truncation_size } = options.bar.windowtitle;
|
||||
|
||||
return {
|
||||
component: Widget.Box({
|
||||
className: Utils.merge([options.theme.bar.buttons.style.bind("value"), options.bar.windowtitle.label.bind("value")], (style, showLabel) => {
|
||||
className: Utils.merge([options.theme.bar.buttons.style.bind("value"), label.bind("value")], (style, showLabel) => {
|
||||
const styleMap = {
|
||||
default: "style1",
|
||||
split: "style2",
|
||||
@@ -144,16 +166,25 @@ const ClientTitle = () => {
|
||||
};
|
||||
return `windowtitle ${styleMap[style]} ${!showLabel ? "no-label" : ""}`;
|
||||
}),
|
||||
children: options.bar.windowtitle.label.bind("value").as((showLabel) => {
|
||||
const titleIcon = Widget.Label({
|
||||
children:
|
||||
Utils.merge(
|
||||
[hyprland.active.bind("client"), custom_title.bind("value"), class_name.bind("value"), label.bind("value"),
|
||||
icon.bind("value"), truncation.bind("value"), truncation_size.bind("value")],
|
||||
(client, useCustomTitle, useClassName, showLabel, showIcon, truncate, truncationSize) => {
|
||||
const children: Label<any>[] = [];
|
||||
if (showIcon) {
|
||||
children.push(Widget.Label({
|
||||
class_name: "bar-button-icon windowtitle txt-icon bar",
|
||||
label: hyprland.active.bind("client").as((v) => filterTitle(v).icon),
|
||||
});
|
||||
const titleLabel = Widget.Label({
|
||||
class_name: "bar-button-label windowtitle",
|
||||
label: hyprland.active.bind("client").as((v) => filterTitle(v).label),
|
||||
});
|
||||
return showLabel ? [titleIcon, titleLabel] : [titleIcon];
|
||||
label: filterTitle(client).icon,
|
||||
}));
|
||||
}
|
||||
if (showLabel) {
|
||||
children.push(Widget.Label({
|
||||
class_name: `bar-button-label windowtitle ${showIcon ? "" : "no-icon"}`,
|
||||
label: truncateTitle(getTitle(client, useCustomTitle, useClassName), truncate ? truncationSize : -1),
|
||||
}));
|
||||
}
|
||||
return children;
|
||||
}),
|
||||
}),
|
||||
isVisible: true,
|
||||
|
||||
@@ -814,8 +814,13 @@ const options = mkOptions(OPTIONS, {
|
||||
icon: opt(""),
|
||||
},
|
||||
windowtitle: {
|
||||
custom_title: opt(true),
|
||||
title_map: opt([]),
|
||||
class_name: opt(true),
|
||||
label: opt(true),
|
||||
icon: opt(true),
|
||||
truncation: opt(true),
|
||||
truncation_size: opt(50),
|
||||
},
|
||||
workspaces: {
|
||||
show_icons: opt(false),
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
.bar-button-label.windowtitle {
|
||||
color: if($bar-buttons-monochrome, $bar-buttons-text, $bar-buttons-windowtitle-text);
|
||||
margin-left: $bar-buttons-windowtitle-spacing;
|
||||
|
||||
&.no-icon {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.style2 {
|
||||
|
||||
@@ -220,22 +220,50 @@ export const BarSettings = (): Scrollable<Gtk.Widget, Gtk.Widget> => {
|
||||
*/
|
||||
Header("Window Titles"),
|
||||
Option({
|
||||
opt: options.bar.windowtitle.label,
|
||||
title: "Show Window Title Label",
|
||||
type: "boolean",
|
||||
}),
|
||||
Option({
|
||||
opt: options.theme.bar.buttons.windowtitle.spacing,
|
||||
title: "Inner Spacing",
|
||||
subtitle: "Spacing between the icon and the label inside the buttons.",
|
||||
type: "string",
|
||||
opt: options.bar.windowtitle.custom_title,
|
||||
title: 'Use Custom Title',
|
||||
type: 'boolean'
|
||||
}),
|
||||
Option({
|
||||
opt: options.bar.windowtitle.title_map,
|
||||
title: "Window Title Mappings",
|
||||
subtitle: "Wiki Link: https://hyprpanel.com/configuration/panel.html#window-title-mappings",
|
||||
type: "object",
|
||||
subtitleLink: "https://hyprpanel.com/configuration/panel.html#window-title-mappings",
|
||||
title: 'Window Title Mappings',
|
||||
subtitle: 'Only applicable if Show Custom Title is enabled\nWiki Link: https://hyprpanel.com/configuration/panel.html#window-title-mappings',
|
||||
type: 'object',
|
||||
subtitleLink: 'https://hyprpanel.com/configuration/panel.html#window-title-mappings'
|
||||
}),
|
||||
Option({
|
||||
opt: options.bar.windowtitle.class_name,
|
||||
title: 'Use Class Name',
|
||||
subtitle: 'Only applicable if Show Custom Title is disabled\nDisplays the window\'s class name instead of its title.',
|
||||
type: 'boolean'
|
||||
}),
|
||||
Option({
|
||||
opt: options.bar.windowtitle.label,
|
||||
title: 'Show Window Title Label',
|
||||
type: 'boolean'
|
||||
}),
|
||||
Option({
|
||||
opt: options.bar.windowtitle.icon,
|
||||
title: 'Show Icon',
|
||||
type: 'boolean'
|
||||
}),
|
||||
Option({
|
||||
opt: options.bar.windowtitle.truncation,
|
||||
title: 'Truncate Window Title',
|
||||
subtitle: 'Will truncate the window title to the specified size below.',
|
||||
type: 'boolean'
|
||||
}),
|
||||
Option({
|
||||
opt: options.bar.windowtitle.truncation_size,
|
||||
title: 'Truncation Size',
|
||||
type: 'number',
|
||||
min: 10
|
||||
}),
|
||||
Option({
|
||||
opt: options.theme.bar.buttons.windowtitle.spacing,
|
||||
title: 'Inner Spacing',
|
||||
subtitle: 'Spacing between the icon and the label inside the buttons.',
|
||||
type: 'string'
|
||||
}),
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user