1*00b2deccSnicm /* $OpenBSD: names.c,v 1.29 2015/08/29 00:29:15 nicm Exp $ */ 2311827fbSnicm 3311827fbSnicm /* 4311827fbSnicm * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> 5311827fbSnicm * 6311827fbSnicm * Permission to use, copy, modify, and distribute this software for any 7311827fbSnicm * purpose with or without fee is hereby granted, provided that the above 8311827fbSnicm * copyright notice and this permission notice appear in all copies. 9311827fbSnicm * 10311827fbSnicm * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11311827fbSnicm * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12311827fbSnicm * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13311827fbSnicm * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14311827fbSnicm * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15311827fbSnicm * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16311827fbSnicm * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17311827fbSnicm */ 18311827fbSnicm 19311827fbSnicm #include <sys/types.h> 20311827fbSnicm 21311827fbSnicm #include <ctype.h> 22311827fbSnicm #include <libgen.h> 237d053cf9Snicm #include <stdlib.h> 24311827fbSnicm #include <string.h> 25311827fbSnicm 26311827fbSnicm #include "tmux.h" 27311827fbSnicm 28*00b2deccSnicm void name_time_callback(int, short, void *); 29*00b2deccSnicm int name_time_expired(struct window *, struct timeval *); 30f5015e68Snicm 31311827fbSnicm void 32*00b2deccSnicm name_time_callback(unused int fd, unused short events, void *arg) 33311827fbSnicm { 34*00b2deccSnicm struct window *w = arg; 35f5015e68Snicm 36*00b2deccSnicm /* The event loop will call check_window_name for us on the way out. */ 37*00b2deccSnicm log_debug("@%u name timer expired", w->id); 38*00b2deccSnicm } 39f5015e68Snicm 40*00b2deccSnicm int 41*00b2deccSnicm name_time_expired(struct window *w, struct timeval *tv) 42*00b2deccSnicm { 43*00b2deccSnicm struct timeval offset; 44*00b2deccSnicm 45*00b2deccSnicm timersub(tv, &w->name_time, &offset); 46*00b2deccSnicm if (offset.tv_sec != 0 || offset.tv_usec > NAME_INTERVAL) 47*00b2deccSnicm return (0); 48*00b2deccSnicm return (NAME_INTERVAL - offset.tv_usec); 49f5015e68Snicm } 50f5015e68Snicm 51f5015e68Snicm void 52*00b2deccSnicm check_window_name(struct window *w) 53f5015e68Snicm { 54*00b2deccSnicm struct timeval tv, next; 55203ea44bSnicm char *name; 56*00b2deccSnicm int left; 57311827fbSnicm 58a3560846Snicm if (w->active == NULL) 59a3560846Snicm return; 60a3560846Snicm 61*00b2deccSnicm if (!options_get_number(&w->options, "automatic-rename")) 62*00b2deccSnicm return; 63*00b2deccSnicm 64*00b2deccSnicm if (~w->active->flags & PANE_CHANGED) { 65*00b2deccSnicm log_debug("@%u active pane not changed", w->id); 6691e80530Snicm return; 67f5015e68Snicm } 68*00b2deccSnicm log_debug("@%u active pane changed", w->id); 69b0b8e5bfSnicm 70*00b2deccSnicm gettimeofday(&tv, NULL); 71*00b2deccSnicm left = name_time_expired(w, &tv); 72*00b2deccSnicm if (left != 0) { 73*00b2deccSnicm if (!event_initialized(&w->name_event)) 74*00b2deccSnicm evtimer_set(&w->name_event, name_time_callback, w); 75*00b2deccSnicm if (!evtimer_pending(&w->name_event, NULL)) { 76*00b2deccSnicm log_debug("@%u name timer queued (%d left)", w->id, left); 77*00b2deccSnicm timerclear(&next); 78*00b2deccSnicm next.tv_usec = left; 79*00b2deccSnicm event_add(&w->name_event, &next); 80*00b2deccSnicm } else 81*00b2deccSnicm log_debug("@%u name timer already queued (%d left)", w->id, left); 825b9cc8aaSnicm return; 83*00b2deccSnicm } 84*00b2deccSnicm memcpy(&w->name_time, &tv, sizeof w->name_time); 85*00b2deccSnicm if (event_initialized(&w->name_event)) 86*00b2deccSnicm evtimer_del(&w->name_event); 87*00b2deccSnicm 885b9cc8aaSnicm w->active->flags &= ~PANE_CHANGED; 895b9cc8aaSnicm 90203ea44bSnicm name = format_window_name(w); 91203ea44bSnicm if (strcmp(name, w->name) != 0) { 92*00b2deccSnicm log_debug("@%u new name %s (was %s)", w->id, name, w->name); 93203ea44bSnicm window_set_name(w, name); 94311827fbSnicm server_status_window(w); 95*00b2deccSnicm } else 96*00b2deccSnicm log_debug("@%u name not changed (still %s)", w->id, w->name); 97*00b2deccSnicm 98203ea44bSnicm free(name); 99311827fbSnicm } 100311827fbSnicm 101311827fbSnicm char * 102311827fbSnicm default_window_name(struct window *w) 103311827fbSnicm { 10458034113Snicm char *cmd, *s; 10558034113Snicm 10658034113Snicm cmd = cmd_stringify_argv(w->active->argc, w->active->argv); 10758034113Snicm if (cmd != NULL && *cmd != '\0') 10858034113Snicm s = parse_window_name(cmd); 10958034113Snicm else 11058034113Snicm s = parse_window_name(w->active->shell); 11158034113Snicm free(cmd); 11258034113Snicm return (s); 113311827fbSnicm } 114311827fbSnicm 115311827fbSnicm char * 116203ea44bSnicm format_window_name(struct window *w) 117203ea44bSnicm { 118203ea44bSnicm struct format_tree *ft; 119203ea44bSnicm char *fmt, *name; 120203ea44bSnicm 121203ea44bSnicm ft = format_create(); 122f426771eSnicm format_defaults_window(ft, w); 123f426771eSnicm format_defaults_pane(ft, w->active); 124203ea44bSnicm 125203ea44bSnicm fmt = options_get_string(&w->options, "automatic-rename-format"); 126203ea44bSnicm name = format_expand(ft, fmt); 127203ea44bSnicm 128203ea44bSnicm format_free(ft); 129203ea44bSnicm return (name); 130203ea44bSnicm } 131203ea44bSnicm 132203ea44bSnicm char * 13366fd4858Snicm parse_window_name(const char *in) 134311827fbSnicm { 13566fd4858Snicm char *copy, *name, *ptr; 136311827fbSnicm 137311827fbSnicm name = copy = xstrdup(in); 13866fd4858Snicm if (strncmp(name, "exec ", (sizeof "exec ") - 1) == 0) 13966fd4858Snicm name = name + (sizeof "exec ") - 1; 140311827fbSnicm 141203ea44bSnicm while (*name == ' ' || *name == '-') 142311827fbSnicm name++; 143311827fbSnicm if ((ptr = strchr(name, ' ')) != NULL) 144311827fbSnicm *ptr = '\0'; 145311827fbSnicm 146311827fbSnicm if (*name != '\0') { 147311827fbSnicm ptr = name + strlen(name) - 1; 1483619f6a1Sray while (ptr > name && !isalnum((u_char)*ptr)) 149311827fbSnicm *ptr-- = '\0'; 150311827fbSnicm } 151311827fbSnicm 152311827fbSnicm if (*name == '/') 153311827fbSnicm name = basename(name); 154311827fbSnicm name = xstrdup(name); 1557d053cf9Snicm free(copy); 156311827fbSnicm return (name); 157311827fbSnicm } 158