Skip to content

Commit 1f03e13

Browse files
committed
Add run new command
1 parent 3f07945 commit 1f03e13

File tree

13 files changed

+352
-121
lines changed

13 files changed

+352
-121
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Edit keyboard.c to modify.
4040
* **Win+f** Toggle fullscreen.
4141
* **Win+r** Restart command.
4242
* **Win+Space** Replace with new command.
43+
* **Win+Enter** Run new command.
4344
* **Win+q** Close.
4445

4546
_Minimize_ means window is explicitly hidden and needs to be reopened manually.

action.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ void send_delete_window(struct pane *, Display *);
1717
void send_take_focus(struct pane *p, Display *d);
1818
void send_message(Atom a, Window w, Display *d);
1919

20-
static void edit_command(struct pane *p, struct layout *l);
20+
static int edit_command(struct pane *p, struct layout *l);
21+
static void new_command(struct pane *p, struct layout *l);
2122

2223
int
2324
handle_action(Display *display, XContext context, int op, int target,
@@ -39,6 +40,9 @@ handle_action(Display *display, XContext context, int op, int target,
3940
case EditCommand:
4041
edit_command(focus, layout);
4142
break;
43+
case NewCommand:
44+
new_command(focus, layout);
45+
break;
4246
case RestartCommand:
4347
if (focus != NULL) {
4448
if (XGetCommand(layout->display, focus->window,
@@ -146,20 +150,42 @@ handle_action(Display *display, XContext context, int op, int target,
146150
}
147151

148152
static void
153+
new_command(struct pane *focus, struct layout *l)
154+
{
155+
struct pane *p;
156+
157+
p = create_empty_pane(l, l->column->x);
158+
manage_pane(p, l->column, focus);
159+
160+
XMapWindow(l->display, p->frame);
161+
XMapSubwindows(l->display, p->frame);
162+
163+
draw_frame(p, l);
164+
focus_pane(p, l);
165+
if (edit_command(p, l) == 0)
166+
close_pane(p, l);
167+
}
168+
169+
static int
149170
edit_command(struct pane *p, struct layout *l)
150171
{
151172
p->flags |= PF_EDIT;
152173
draw_frame(p, l);
153174
if (prompt_read(&p->prompt)) {
154175
p->flags |= PF_WANT_RESTART;
155176
close_pane(p, l);
177+
return 1;
156178
}
179+
return 0;
157180
}
158181

159182
void
160183
close_pane(struct pane *p, struct layout *l)
161184
{
162-
if (!(p->flags & PF_HAS_DELWIN)) {
185+
if (p->flags & PF_EMPTY) {
186+
p->name = NULL;
187+
observedestroy(l->display, l->context, p->frame, l);
188+
} else if (!(p->flags & PF_HAS_DELWIN)) {
163189
XKillClient(l->display, p->window);
164190
observedestroy(l->display, l->context, p->window, l);
165191
return;

cocowm.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ main(int argc, char *argv[])
1818
XEvent event;
1919
static struct layout layout;
2020
int columns, running;
21-
struct column *columns_head;
2221
struct pane *focus;
2322
Display *display;
2423
XContext context;
@@ -76,8 +75,9 @@ main(int argc, char *argv[])
7675
bind_keys(display, DefaultRootWindow(display));
7776
#endif
7877

78+
XSync(display, False);
79+
7980
running = 1;
80-
columns_head = NULL;
8181
focus = NULL;
8282
while (running) {
8383
XNextEvent(display, &event);
@@ -163,6 +163,7 @@ capture_existing_windows(struct layout *l)
163163
TRACE_END("captured %lx, created %s",
164164
children[i], PANE_STR(p));
165165
}
166+
166167
#if 0
167168
interceptmap(display, context, children[i], attrib.x);
168169
#endif

create.c

Lines changed: 87 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,90 @@
66
static void update_size_hints(struct pane *, XWindowAttributes *, Display *);
77
static void update_hints(struct pane *, Display *);
88

9+
struct pane *
10+
create_empty_pane(struct layout *l, int x)
11+
{
12+
struct pane *p;
13+
static unsigned long n_panes;
14+
XGCValues v;
15+
XSetWindowAttributes sa;
16+
int y, w, h, bw, depth, class, mask;
17+
Visual *visual;
18+
Display *dpy = l->display;
19+
Window parent;
20+
struct column *column;
21+
22+
p = calloc(1, sizeof(struct pane));
23+
if (p == NULL)
24+
err(1, "creating pane");
25+
26+
p->name = "(empty pane)";
27+
p->flags |= PF_EMPTY;
28+
p->number = ++n_panes;
29+
column = find_column(l->head, x);
30+
31+
XGetGCValues(l->display, l->normal_gc, GCBackground, &v);
32+
33+
/*
34+
* Create frame.
35+
*/
36+
parent = DefaultRootWindow(dpy);
37+
x = column->x;
38+
y = 0;
39+
w = column->width;
40+
h = l->titlebar_height_px;
41+
bw = 0;
42+
depth = CopyFromParent;
43+
class = InputOutput;
44+
visual = CopyFromParent;
45+
mask = CWEventMask | CWBackPixel;
46+
sa.event_mask = ButtonPressMask | ButtonReleaseMask | ExposureMask;
47+
sa.background_pixel = v.background;
48+
49+
p->frame = XCreateWindow(
50+
dpy, parent, x, y, w, h, bw, depth, class, visual, mask, &sa);
51+
p->height = h + 10;
52+
53+
prompt_init(&p->prompt, p, l);
54+
55+
/*
56+
* Create close button.
57+
*/
58+
parent = p->frame;
59+
x = column->width - l->font_height_px;
60+
w = l->font_height_px;
61+
mask |= CWWinGravity;
62+
sa.win_gravity = NorthEastGravity;
63+
64+
p->close_button = XCreateWindow(
65+
dpy, parent, x, y, w, h, bw, depth, class, visual, mask, &sa);
66+
67+
/*
68+
* Create keep open button.
69+
*/
70+
x -= l->font_height_px;
71+
72+
p->maximize_button = XCreateWindow(
73+
dpy, parent, x, y, w, h, bw, depth, class, visual, mask, &sa);
74+
75+
/*
76+
* Set names for debugging.
77+
*/
78+
XStoreName(dpy, p->frame, "cocowm frame");
79+
XStoreName(dpy, p->close_button, "cocowm close button");
80+
XStoreName(dpy, p->maximize_button, "cocowm keep open button");
81+
82+
/*
83+
* Set associations.
84+
*/
85+
XSaveContext(dpy, p->frame, l->context, (XPointer) p);
86+
XSaveContext(dpy, p->maximize_button, l->context, (XPointer) p);
87+
XSaveContext(dpy, p->close_button, l->context, (XPointer) p);
88+
89+
XSync(dpy, False);
90+
return p;
91+
}
92+
993
/*
1094
* Creates a managed window (a pane in our terminology) by reparenting
1195
* an unmanaged window (w) with a frame that allows control of the
@@ -23,23 +107,17 @@ static void update_hints(struct pane *, Display *);
23107
struct pane *
24108
create_pane(Window w, struct layout *l)
25109
{
26-
static unsigned long n_panes;
27110
struct pane *p;
28111
XWindowAttributes a;
29112
int rheight;
30-
XGCValues v;
31113
XSetWindowAttributes sa;
32-
char s[256];
33114

34115
assert(l != NULL);
35116

36117
/* TODO: Take these values from CreateNotify */
37118
if (XGetWindowAttributes(l->display, w, &a) == 0)
38119
assert(0);
39120

40-
if ((p = calloc(1, sizeof(struct pane))) == NULL)
41-
err(1, "managing new window");
42-
43121
/*
44122
* When starting the window manager, we check for
45123
* override_redirect and IsUnmapped but create_pane() is
@@ -59,6 +137,9 @@ create_pane(Window w, struct layout *l)
59137
return NULL;
60138
}
61139

140+
p = create_empty_pane(l, a.x);
141+
p->flags &= ~PF_EMPTY;
142+
62143
/* TODO: Get this from createnotify or something */
63144
XFetchName(l->display, w, &p->name);
64145

@@ -69,15 +150,12 @@ create_pane(Window w, struct layout *l)
69150
XSetWindowBorderWidth(l->display, w, 10);
70151
#endif
71152

72-
p->number = ++n_panes;
73153
p->window = w;
74154

75155
TRACE("create: Original window size: %d,%d", a.width, a.height);
76156

77157
update_hints(p, l->display);
78-
79158
update_size_hints(p, &a, l->display);
80-
81159
read_pane_protocols(p, l->display);
82160

83161
if (p->flags & PF_MINIMIZED)
@@ -95,90 +173,14 @@ create_pane(Window w, struct layout *l)
95173

96174
TRACE("create: p->height is: %d", p->height);
97175

98-
/* TODO: Is this necessary for moving pane to a nice place? */
99-
#if 0
100-
a.x = x;
101-
#endif
102-
103-
XGetGCValues(l->display, l->normal_gc, GCBackground, &v);
104-
105-
sa.event_mask = ButtonPressMask | ButtonReleaseMask | ExposureMask;
106-
sa.background_pixel = v.background;
107-
p->frame = XCreateWindow(l->display, DefaultRootWindow(l->display),
108-
a.x, a.y, l->column->width, p->height,
109-
0, CopyFromParent, InputOutput,
110-
CopyFromParent, CWEventMask | CWBackPixel,
111-
&sa);
112-
113-
prompt_init(&p->prompt, p, l);
114-
115-
snprintf(s, sizeof(s), "cocowm frame for 0x%lx (%s)", w, p->name);
116-
XStoreName(l->display, p->frame, s);
117-
118-
TRACE("create: create pane frame is %lx", p->frame);
119-
XSync(l->display, False);
120-
sa.win_gravity = NorthEastGravity;
121-
p->close_button = XCreateWindow(l->display, p->frame,
122-
l->column->width - l->font_height_px, 0,
123-
l->font_height_px, (l->titlebar_height_px),
124-
0, CopyFromParent, InputOutput,
125-
CopyFromParent,
126-
CWEventMask | CWBackPixel | CWWinGravity, &sa);
127-
TRACE("create: create pane close is %lx", p->close_button);
128-
129-
snprintf(s, sizeof(s), "cocowm close_button for 0x%lx (%s)", w, p->name);
130-
XStoreName(l->display, p->close_button, s);
131-
132-
XSync(l->display, False);
133-
p->maximize_button = XCreateWindow(l->display, p->frame,
134-
l->column->width - (l->font_height_px * 2),
135-
0, l->font_height_px, (l->titlebar_height_px),
136-
0, CopyFromParent, InputOutput,
137-
CopyFromParent,
138-
CWEventMask | CWBackPixel | CWWinGravity, &sa);
139-
140-
snprintf(s, sizeof(s), "cocowm maximize_button for 0x%lx (%s)", w, p->name);
141-
XStoreName(l->display, p->maximize_button, s);
142-
143-
TRACE("create: create pane maximize is %lx", p->maximize_button);
144-
XSync(l->display, False);
145-
146-
XGetGCValues(l->display, l->column_gc, GCForeground, &v);
147-
#if 0
148-
sa.background_pixel = v.foreground;
149-
p->column_button = XCreateWindow(l->display, p->frame,
150-
0, 0, 20, 20,
151-
0, CopyFromParent, InputOutput,
152-
CopyFromParent,
153-
CWBackPixel, &sa);
154-
#endif
155-
156176
XGetIconName(l->display, w, &p->icon_name);
157177

158178
XSaveContext(l->display, w, l->context, (XPointer) p);
159-
XSaveContext(l->display, p->frame, l->context, (XPointer) p);
160-
XSaveContext(l->display, p->maximize_button, l->context, (XPointer) p);
161-
XSaveContext(l->display, p->close_button, l->context, (XPointer) p);
162-
163-
#if 0
164-
XSelectInput(l->display, w, PropertyChangeMask);
165-
#endif
166-
167179
XAddToSaveSet(l->display, w);
168180

169181
XMapWindow(l->display, p->frame);
170182
XMapSubwindows(l->display, p->frame);
171183

172-
#if 0
173-
XReparentWindow(l->display, w, p->frame, 0, (l->titlebar_height_px));
174-
175-
/* TODO: Or move these to Reparent window event? */
176-
if (!(p->flags & PF_MINIMIZED))
177-
XMapWindow(l->display, w);
178-
179-
XMapSubwindows(l->display, p->frame);
180-
#endif
181-
182184
/*
183185
* Required for click-to-focus.
184186
*/

draw.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,13 @@ draw_frame(struct pane *p, struct layout *l)
117117

118118
XClearWindow(l->display, p->frame);
119119

120-
snprintf(number_str, sizeof(number_str), "%ld%c%c%c%c%c: ", p->number,
120+
snprintf(number_str, sizeof(number_str), "%ld%c%c%c%c%c%c: ", p->number,
121121
p->flags & PF_MINIMIZED ? 'M' : 'm',
122122
p->flags & PF_HIDDEN ? 'H' : 'h',
123123
p->flags & PF_HIDE_OTHERS_LEADER ? 'L' : 'l',
124124
p->flags & PF_KEEP_OPEN ? 'O' : 'o',
125-
p->flags & PF_EDIT ? 'E' : 'e');
125+
p->flags & PF_EDIT ? 'E' : 'e',
126+
p->flags & PF_EMPTY ? 'Y' : 'y');
126127

127128
XDrawString(l->display, p->frame, l->normal_gc,
128129
1 + l->fs->min_bounds.lbearing, 1 + l->fs->ascent, number_str,

event.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ observemap(Display *display, XContext context, Window window,
503503
}
504504
}
505505

506-
if (window == pane->frame) {
506+
if (window == pane->frame && !(pane->flags & PF_EMPTY)) {
507507
TRACE("Reparent from MapNotify");
508508
XReparentWindow(display, pane->window, pane->frame, 0, 20);
509509
}

extern.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ struct pane
9191
#define PF_HIDDEN (1 << 16)
9292
#define PF_HIDE_OTHERS_LEADER (1 << 17)
9393
#define PF_EDIT (1 << 18)
94+
#define PF_EMPTY (1 << 19)
95+
96+
#define PF_WITHOUT_WINDOW (PF_EMPTY | PF_MINIMIZED | PF_HIDDEN)
9497

9598
int flags;
9699

@@ -195,6 +198,7 @@ enum action {
195198
Fullscreen,
196199
PrevFocus,
197200
EditCommand,
201+
NewCommand,
198202
RestartCommand,
199203
ToggleMode
200204
};
@@ -259,6 +263,7 @@ find_column_by_hpos(int x, struct column *head);
259263
struct pane* create_pane (Window, Window, int);
260264
#endif
261265

266+
struct pane *create_empty_pane(struct layout *, int);
262267
struct pane * create_pane(Window w, struct layout *l);
263268

264269
struct pane * get_prev_pane(struct pane *pane);

0 commit comments

Comments
 (0)