diff
wm.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 79 insertions(+), 11 deletions(-)
diff --git a/wm.c b/wm.c
index d9453e0..87647cd 100644
--- a/wm.c
+++ b/wm.c
@@ -27,8 +27,10 @@ static int window_workspace[max_windows], window_count, current_workspace;
static Atom net_wm_desktop_atom;
#ifdef BAR
static Atom wm_bar_margin_x_atom, wm_bar_margin_y_atom, wm_bar_bottom_atom;
+static Atom net_wm_name_atom, utf8_string_atom;
#endif
static int is_root_child(Display *display, Window root_window, Window window);
+static void select_window_events(Display *display, Window window);
static int
find_window_index(Window window)
@@ -94,12 +96,47 @@ place_window_at_pointer(Display *display, Window root_window, Window window)
#ifdef BAR
static void
-refresh_bar(void)
+set_bar_title_from_window(Display *display, Window window)
+{
+ Atom actual_type;
+ int actual_format;
+ unsigned long nitems, bytes_after;
+ unsigned char *prop_data;
+ char *window_name;
+
+ prop_data = NULL;
+ if (window != None && window != PointerRoot &&
+ XGetWindowProperty(display, window, net_wm_name_atom, 0, 2048, False,
+ utf8_string_atom, &actual_type, &actual_format, &nitems, &bytes_after,
+ &prop_data) == Success &&
+ prop_data != NULL && actual_type == utf8_string_atom &&
+ actual_format == 8 && nitems > 0) {
+ bar_set_title((char *)prop_data);
+ XFree(prop_data);
+ return;
+ }
+ if (prop_data != NULL)
+ XFree(prop_data);
+ window_name = NULL;
+ if (window != None && window != PointerRoot &&
+ XFetchName(display, window, &window_name) && window_name != NULL) {
+ bar_set_title(window_name);
+ XFree(window_name);
+ return;
+ }
+ bar_set_title("");
+}
+
+static void
+refresh_bar(Display *display)
{
static int tags[num_workspaces] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ Window focused_window;
+ int revert_to;
bar_set_tags(tags, num_workspaces, current_workspace);
- bar_set_title("wm");
+ XGetInputFocus(display, &focused_window, &revert_to);
+ set_bar_title_from_window(display, focused_window);
bar_set_status("");
bar_draw();
}
@@ -236,6 +273,12 @@ get_window_attrs(Display *display, Window window, XWindowAttributes *window_attr
window_attrs->override_redirect = True;
}
+static void
+select_window_events(Display *display, Window window)
+{
+ XSelectInput(display, window, EnterWindowMask | PropertyChangeMask);
+}
+
static int
is_managed_window(Display *display, Window root_window, Window window)
{
@@ -259,6 +302,7 @@ track_windows(Display *display, Window root_window)
if (!is_managed_window(display, root_window, children[i]))
continue;
+ select_window_events(display, children[i]);
window_index = get_window_index(children[i]);
desktop = get_window_desktop(display, children[i]);
if (window_index >= 0 && desktop >= 0)
@@ -335,6 +379,8 @@ main(int argc, char **argv)
wm_bar_margin_x_atom = XInternAtom(display, "_WM_BAR_MARGIN_X", False);
wm_bar_margin_y_atom = XInternAtom(display, "_WM_BAR_MARGIN_Y", False);
wm_bar_bottom_atom = XInternAtom(display, "_WM_BAR_BOTTOM", False);
+ net_wm_name_atom = XInternAtom(display, "_NET_WM_NAME", False);
+ utf8_string_atom = XInternAtom(display, "UTF8_STRING", False);
#endif
XSelectInput(display, root_window, SubstructureNotifyMask | StructureNotifyMask);
track_windows(display, root_window);
@@ -348,7 +394,7 @@ main(int argc, char **argv)
bar_set_margins(read_root_int_property(display, root_window, wm_bar_margin_x_atom, 0),
read_root_int_property(display, root_window, wm_bar_margin_y_atom, 0));
bar_set_bottom(read_root_int_property(display, root_window, wm_bar_bottom_atom, 0) ? 1 : 0);
- refresh_bar();
+ refresh_bar(display);
#endif
grab_button_variants(display, 1, 0, root_window, GrabModeSync);
@@ -371,17 +417,17 @@ main(int argc, char **argv)
if (command == cmd_bar_position) {
bar_set_bottom(value ? 1 : 0);
write_root_int_property(display, root_window, wm_bar_bottom_atom, value ? 1 : 0);
- refresh_bar();
+ refresh_bar(display);
continue;
} else if (command == cmd_bar_margin_x) {
bar_set_margins(value, -1);
write_root_int_property(display, root_window, wm_bar_margin_x_atom, value);
- refresh_bar();
+ refresh_bar(display);
continue;
} else if (command == cmd_bar_margin_y) {
bar_set_margins(-1, value);
write_root_int_property(display, root_window, wm_bar_margin_y_atom, value);
- refresh_bar();
+ refresh_bar(display);
continue;
}
#endif
@@ -405,7 +451,7 @@ main(int argc, char **argv)
ewmh_set_current_desktop(display, root_window, current_workspace);
ewmh_sync(display, root_window, windows, window_workspace, window_count);
#ifdef BAR
- refresh_bar();
+ refresh_bar(display);
#endif
} else if (command == cmd_move) {
XGetInputFocus(display, &focused_window, &j);
@@ -419,7 +465,7 @@ main(int argc, char **argv)
XUnmapWindow(display, focused_window);
ewmh_sync(display, root_window, windows, window_workspace, window_count);
#ifdef BAR
- refresh_bar();
+ refresh_bar(display);
#endif
}
}
@@ -428,7 +474,7 @@ main(int argc, char **argv)
remove_window(event.xdestroywindow.window);
ewmh_sync(display, root_window, windows, window_workspace, window_count);
#ifdef BAR
- refresh_bar();
+ refresh_bar(display);
#endif
} else if (event.type == MapNotify) {
Window mapped_window;
@@ -438,10 +484,11 @@ main(int argc, char **argv)
continue;
if (find_window_index(mapped_window) < 0) {
place_window_at_pointer(display, root_window, mapped_window);
+ select_window_events(display, mapped_window);
get_window_index(mapped_window);
ewmh_sync(display, root_window, windows, window_workspace, window_count);
#ifdef BAR
- refresh_bar();
+ refresh_bar(display);
#endif
}
} else if (event.type == ButtonPress && event.xbutton.subwindow != None) {
@@ -458,7 +505,7 @@ main(int argc, char **argv)
window_workspace[j] = current_workspace;
ewmh_sync(display, root_window, windows, window_workspace, window_count);
#ifdef BAR
- refresh_bar();
+ refresh_bar(display);
#endif
if (!(event.xbutton.state & mod_key) && event.xbutton.button == 1) {
XAllowEvents(display, ReplayPointer, event.xbutton.time);
@@ -480,6 +527,27 @@ main(int argc, char **argv)
is_dragging = 1;
} else if (event.type == ButtonPress && event.xbutton.subwindow == None) {
XAllowEvents(display, AsyncPointer, event.xbutton.time);
+ } else if (event.type == EnterNotify && event.xcrossing.window != None) {
+ Window hover_window;
+
+ hover_window = event.xcrossing.window;
+ if (event.xcrossing.mode != NotifyNormal ||
+ event.xcrossing.detail == NotifyInferior)
+ continue;
+ if (!is_managed_window(display, root_window, hover_window))
+ continue;
+ XSetInputFocus(display, hover_window, RevertToPointerRoot, CurrentTime);
+ ewmh_set_active_window(display, root_window, hover_window);
+#ifdef BAR
+ refresh_bar(display);
+#endif
+ } else if (event.type == PropertyNotify) {
+#ifdef BAR
+ if (event.xproperty.state == PropertyNewValue &&
+ (event.xproperty.atom == net_wm_name_atom ||
+ event.xproperty.atom == XA_WM_NAME))
+ refresh_bar(display);
+#endif
} else if (event.type == MotionNotify && is_dragging) {
int x_diff, y_diff;