v0.11.0 dc50343

workspace_css.go RawHistoryFolder

1// workspace_css.go - CSS generation and styling for workspace panes
2package browser
3
4import (
5	"fmt"
6	"strings"
7
8	"github.com/bnema/dumber/internal/config"
9	"github.com/bnema/dumber/pkg/webkit"
10)
11
12// Helper functions for stacked pane CSS colors
13
14// getStackTitleBg returns the background color for stack titles based on theme
15func getStackTitleBg(isDark bool) string {
16	if isDark {
17		return "#404040"
18	}
19	return "#f0f0f0"
20}
21
22// getStackTitleHoverBg returns the hover background color for stack titles based on theme
23func getStackTitleHoverBg(isDark bool) string {
24	if isDark {
25		return "#505050"
26	}
27	return "#e0e0e0"
28}
29
30// getStackTitleTextColor returns the text color for stack titles based on theme
31func getStackTitleTextColor(isDark bool) string {
32	if isDark {
33		return "#ffffff"
34	}
35	return "#333333"
36}
37
38// getActivePaneBorderColor returns the border color for active panes based on config and theme
39func getActivePaneBorderColor(styling config.WorkspaceStylingConfig, isDark bool) string {
40	// Use configured border color if set
41	if styling.BorderColor != "" {
42		// Check if it's a GTK theme variable (starts with @)
43		if strings.HasPrefix(styling.BorderColor, "@") {
44			return styling.BorderColor
45		}
46		// Return the configured color as-is (could be hex, rgb, etc.)
47		return styling.BorderColor
48	}
49
50	// Fallback to hardcoded colors based on theme
51	if isDark {
52		return "#4A90E2" // Deeper blue pastel for dark theme
53	}
54	return "#87CEEB" // Sky blue pastel for light theme
55}
56
57// generateWorkspaceCSS generates the complete CSS for workspace panes and stacked panes
58func (wm *WorkspaceManager) generateWorkspaceCSS() string {
59	cfg := config.Get()
60	styling := cfg.Workspace.Styling
61
62	// Get appropriate colors based on GTK theme preference
63	var inactiveBorderColor, windowBackgroundColor string
64	isDark := webkit.PrefersDarkTheme()
65	if isDark {
66		inactiveBorderColor = "#333333"   // Dark border for dark theme
67		windowBackgroundColor = "#2b2b2b" // Dark window background
68	} else {
69		inactiveBorderColor = "#dddddd"   // Light border for light theme
70		windowBackgroundColor = "#ffffff" // Light window background
71	}
72
73	activeBorderColor := getActivePaneBorderColor(styling, isDark)
74
75	css := fmt.Sprintf(`window {
76	  background-color: %s;
77	}
78
79	/* Base pane styling - transparent outline for smooth transitions */
80	.workspace-pane, .stacked-pane-container {
81	  outline: 2px solid transparent;
82	  outline-offset: -2px;
83	  transition: outline-color %dms ease-in-out;
84	}
85
86	/* Active pane border styling using outline (no layout impact) */
87	.workspace-pane-active {
88	  outline-color: %s;
89	}
90
91	/* Stacked panes styling */
92	.stacked-pane-container {
93	  background-color: %s;
94	  border-radius: %dpx;
95	}
96
97	/* Active stacked pane container gets the outline color */
98	.stacked-pane-container.workspace-pane-active {
99	  outline-color: %s;
100	}
101
102	.stacked-pane-title {
103	  background-color: %s;
104	  border-bottom: 1px solid %s;
105	  padding: 4px 8px;
106	  min-height: 24px;
107	  transition: background-color %dms ease-in-out;
108	}
109
110	.stacked-pane-title:hover {
111	  background-color: %s;
112	}
113
114	.stacked-pane-title-text {
115	  font-size: 12px;
116	  color: %s;
117	  font-weight: 500;
118	}
119
120	.stacked-pane-favicon {
121	  margin-right: 4px;
122	}
123
124	.stacked-pane-active {
125	  /* Active pane is fully visible */
126	}
127
128	.stacked-pane-collapsed {
129	  /* Collapsed panes are hidden - handled in code via widget visibility */
130	}`,
131		windowBackgroundColor,          // window background
132		styling.TransitionDuration,     // base pane outline transition
133		activeBorderColor,              // workspace-pane-active outline-color
134		windowBackgroundColor,          // stacked-pane-container background
135		styling.BorderRadius,           // stacked-pane-container border-radius
136		activeBorderColor,              // stacked-pane-container.workspace-pane-active outline-color
137		getStackTitleBg(isDark),        // stacked-pane-title background
138		inactiveBorderColor,            // stacked-pane-title border-bottom
139		styling.TransitionDuration,     // stacked-pane-title transition
140		getStackTitleHoverBg(isDark),   // stacked-pane-title:hover background
141		getStackTitleTextColor(isDark), // stacked-pane-title-text color
142	)
143
144	return css
145}
146
147// generateStackedPaneCSS generates the CSS for stacked pane title bars (deprecated - use generateWorkspaceCSS)
148func (wm *WorkspaceManager) generateStackedPaneCSS() string {
149	// Delegate to the new comprehensive CSS generator
150	return wm.generateWorkspaceCSS()
151}
152
153// Global CSS provider tracking to prevent duplication
154var (
155	globalCSSInitialized bool
156	globalCSSContent     string
157)
158
159// ensureWorkspaceStyles ensures that CSS styles are applied for workspace panes
160// Improved to prevent CSS provider duplication by using global CSS tracking
161func (wm *WorkspaceManager) ensureWorkspaceStyles() {
162	if wm == nil {
163		return
164	}
165
166	// Generate CSS content
167	workspaceCSS := wm.generateWorkspaceCSS()
168
169	// Only apply CSS if it hasn't been applied globally or if content changed
170	if !globalCSSInitialized || globalCSSContent != workspaceCSS {
171		webkit.AddCSSProvider(workspaceCSS)
172		globalCSSInitialized = true
173		globalCSSContent = workspaceCSS
174	}
175
176	wm.cssInitialized = true
177}
178
179// ensureStackedPaneStyles ensures that CSS styles are applied for stacked panes (deprecated - use ensureWorkspaceStyles)
180func (wm *WorkspaceManager) ensureStackedPaneStyles() {
181	wm.ensureWorkspaceStyles()
182}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close