TODO: option popup hook, make some exts switchable
TODO: constant offste with automove
TODO: rework colors and blabla section
-TODO: hednod-tabs
-TODO: forward keyevents to subtabs
- changed interpretation of [alpha] colour prefix.
- +option now really sets the option to default, instead of using the
resource value.
- options that require an argument now really _require_ an argument.
+ - the tabbed extension now forwards focus and keys events to th
+ relevant tab window.
+ - tab colours are now configurable and have sensible defaults
+ (initial patch by hednod).
- force refresh of XA_RESOURCE_STRING on virtual reconnect.
- return exit status 2 in urxvtc when urxvtd couldn't be contacted.
- the linux yield hack is back, now using usleep, and enabled only on
}
#endif
-/*{{{ Convert the keypress event into a string */
void
-rxvt_term::lookup_key (XKeyEvent &ev)
+rxvt_term::key_press (XKeyEvent &ev)
{
int ctrl, meta, shft, len;
unsigned int newlen;
int valid_keysym;
char kbuf[KBUFSZ];
+#if ISO_14755
+ if (iso14755buf & ISO_14755_52)
+ return;
+#endif
+
/*
* use Num_Lock to toggle Keypad on/off. If Num_Lock is off, allow an
* escape sequence to toggle the Keypad.
tt_write (kbuf, (unsigned int)len);
}
-/*}}} */
+
+void
+rxvt_term::key_release (XKeyEvent &ev)
+{
+#if (MOUSE_WHEEL && MOUSE_SLIP_WHEELING) || ISO_14755 || ENABLE_PERL
+ KeySym keysym;
+
+ keysym = XLookupKeysym (&ev, ev.state & ShiftMask ? 1 : 0); // sorry, only shift supported :/
+#endif
+
+#if ENABLE_FRILLS || ISO_14755
+ // ISO 14755 support
+ if (iso14755buf)
+ if (iso14755buf & ISO_14755_52)
+ {
+# if ENABLE_OVERLAY
+ scr_overlay_off ();
+# endif
+# if ISO_14755
+ // iso14755 part 5.2 handling: release time
+ // first: controls
+ if ((ev.state & ControlMask)
+ && ((keysym >= 0x40 && keysym <= 0x5f)
+ || (keysym >= 0x61 && keysym <= 0x7f)))
+ {
+ iso14755buf = ISO_14755_51 | 0x2400 | (keysym & 0x1f);
+ commit_iso14755 ();
+
+ return;
+ }
+
+ for (unsigned short *i = iso14755_symtab; i[0]; i+= 2)
+ if (i[0] == keysym)
+ {
+ iso14755buf = ISO_14755_51 | i[1];
+ commit_iso14755 ();
+
+ return;
+ }
+
+ scr_bell ();
+# endif
+ iso14755buf = 0;
+
+ return;
+ }
+ else if ((ev.state & (ShiftMask | ControlMask)) != (ShiftMask | ControlMask))
+ {
+# if ENABLE_OVERLAY
+ scr_overlay_off ();
+# endif
+ if (iso14755buf & ISO_14755_51)
+ commit_iso14755 ();
+#if ISO_14755
+ else if (iso14755buf & ISO_14755_STARTED)
+ {
+ iso14755buf = ISO_14755_52; // iso14755 part 5.2: remember empty begin/end pair
+
+ scr_overlay_new (0, -1, sizeof ("KEYCAP PICTURE INSERT MODE") - 1, 1);
+ scr_overlay_set (0, 0, "KEYCAP PICTURE INSERT MODE");
+ }
+# endif
+ else
+ iso14755buf = 0;
+ }
+#endif
+
+ if (HOOK_INVOKE ((this, HOOK_KEY_RELEASE, DT_XEVENT, &ev, DT_INT, keysym, DT_END)))
+ return;
+
+#if defined(MOUSE_WHEEL) && defined(MOUSE_SLIP_WHEELING)
+ if (!(ev.state & ControlMask))
+ slip_wheel_ev.stop ();
+ else if (keysym == XK_Control_L || keysym == XK_Control_R)
+ mouse_slip_wheel_speed = 0;
+#endif
+}
#if defined (KEYSYM_RESOURCE)
unsigned int
switch (ev.type)
{
case KeyPress:
-#if ISO_14755
- if (!(iso14755buf & ISO_14755_52))
-#endif
- lookup_key (ev.xkey);
-
+ key_press (ev.xkey);
break;
case KeyRelease:
- {
-#if (MOUSE_WHEEL && MOUSE_SLIP_WHEELING) || ISO_14755 || ENABLE_PERL
- KeySym keysym;
-
- keysym = XLookupKeysym (&ev.xkey, ev.xkey.state & ShiftMask ? 1 : 0); // sorry, only shift supported :/
-#endif
-
-#if ENABLE_FRILLS || ISO_14755
- // ISO 14755 support
- if (iso14755buf)
- if (iso14755buf & ISO_14755_52)
- {
-# if ENABLE_OVERLAY
- scr_overlay_off ();
-# endif
-# if ISO_14755
- // iso14755 part 5.2 handling: release time
- // first: controls
- if ((ev.xkey.state & ControlMask)
- && ((keysym >= 0x40 && keysym <= 0x5f)
- || (keysym >= 0x61 && keysym <= 0x7f)))
- {
- iso14755buf = ISO_14755_51 | 0x2400 | (keysym & 0x1f);
- commit_iso14755 ();
- goto skip_switch;
- }
-
- for (unsigned short *i = iso14755_symtab; i[0]; i+= 2)
- if (i[0] == keysym)
- {
- iso14755buf = ISO_14755_51 | i[1];
- commit_iso14755 ();
- goto skip_switch;
- }
-
- scr_bell ();
-# endif
- iso14755buf = 0;
- break;
- }
- else if ((ev.xkey.state & (ShiftMask | ControlMask)) != (ShiftMask | ControlMask))
- {
-# if ENABLE_OVERLAY
- scr_overlay_off ();
-# endif
- if (iso14755buf & ISO_14755_51)
- commit_iso14755 ();
-#if ISO_14755
- else if (iso14755buf & ISO_14755_STARTED)
- {
- iso14755buf = ISO_14755_52; // iso14755 part 5.2: remember empty begin/end pair
-
- scr_overlay_new (0, -1, sizeof ("KEYCAP PICTURE INSERT MODE") - 1, 1);
- scr_overlay_set (0, 0, "KEYCAP PICTURE INSERT MODE");
- }
-# endif
- else
- iso14755buf = 0;
- }
-#endif
-
- if (ev.xany.window == vt
- && HOOK_INVOKE ((this, HOOK_KEY_RELEASE, DT_XEVENT, &ev, DT_INT, keysym, DT_END)))
- break;
-
-#if defined(MOUSE_WHEEL) && defined(MOUSE_SLIP_WHEELING)
- if (!(ev.xkey.state & ControlMask))
- slip_wheel_ev.stop ();
- else if (keysym == XK_Control_L || keysym == XK_Control_R)
- mouse_slip_wheel_speed = 0;
-#endif
- break;
- }
+ key_release (ev.xkey);
+ break;
case ButtonPress:
button_press (ev.xbutton);
break;
}
-skip_switch: ;
-
#if defined(CURSOR_BLINK)
if (OPTION (Opt_cursorBlink) && ev.type == KeyPress)
{
my $ncol = $self->ncol;
my $text = " " x $ncol;
- my $rend = [(urxvt::DEFAULT_RSTYLE | urxvt::RS_RVid) x $ncol];
+ my $rend = [($self->{rs_tabbar}) x $ncol];
my @ofs;
substr $text, 0, 7, "[NEW] |";
- @$rend[0 .. 5] = (urxvt::OVERLAY_RSTYLE) x 6;
+ @$rend[0 .. 5] = ($self->{rs_tab}) x 6;
push @ofs, [0, 6, sub { $_[0]->new_tab }];
my $ofs = 7;
my $len = length $txt;
substr $text, $ofs, $len + 1, "$txt|";
- @$rend[$ofs .. $ofs + $len - 1] = (urxvt::OVERLAY_RSTYLE) x $len
+ @$rend[$ofs .. $ofs + $len - 1] = ($self->{rs_tab}) x $len
if $tab == $self->{cur};
push @ofs, [ $ofs, $ofs + $len, sub { $_[0]->make_current ($tab) } ];
my $tab = $self->{cur};
+ # this is an extremely dirty way to force a configurenotify, but who cares
$tab->XMoveResizeWindow (
$tab->parent,
- 0, $self->{tabheight} - 1,
+ 0, $self->{tabheight} + 1,
$self->width, $self->height - $self->{tabheight}
);
$tab->XMoveResizeWindow (
()
}
+sub on_focus_in {
+ my ($self, $event) = @_;
+
+ $self->{cur}->focus_in;
+
+ ()
+}
+
+sub on_focus_out {
+ my ($self, $event) = @_;
+
+ $self->{cur}->focus_out;
+
+ ()
+}
+
+sub on_key_press {
+ my ($self, $event) = @_;
+
+ $self->{cur}->key_press ($event->{state}, $event->{keycode}, $event->{time});
+
+ 1
+}
+
+sub on_key_release {
+ my ($self, $event) = @_;
+
+ $self->{cur}->key_release ($event->{state}, $event->{keycode}, $event->{time});
+
+ 1
+}
+
sub on_button_press {
1
}
}
$self->resource (int_bwidth => 0);
- $self->resource (name => "URxvt.tab");
+ $self->resource (name => "URxvt.tabbed");
$self->resource (pty_fd => -1);
$self->option ($urxvt::OPTION{scrollBar}, 0);
+ my $fg = $self->x_resource ("tabbar-fg");
+ my $bg = $self->x_resource ("tabbar-bg");
+ my $tabfg = $self->x_resource ("tab-fg");
+ my $tabbg = $self->x_resource ("tab-bg");
+
+ defined $fg or $fg = 3;
+ defined $bg or $bg = 0;
+ defined $tabfg or $tabfg = 0;
+ defined $tabbg or $tabbg = 1;
+
+ $self->{rs_tabbar} = urxvt::SET_COLOR (urxvt::DEFAULT_RSTYLE, $fg + 2, $bg + 2);
+ $self->{rs_tab} = urxvt::SET_COLOR (urxvt::DEFAULT_RSTYLE, $tabfg + 2, $tabbg + 2);
+
()
}
$self->{tabheight} = $self->int_bwidth + $self->fheight + $self->lineSpace;
+ $self->cmd_parse ("\033[?25l");
+
$self->new_tab;
()
void resize_scrollbar ();
// command.C
- void lookup_key (XKeyEvent &ev);
+ void key_press (XKeyEvent &ev);
+ void key_release (XKeyEvent &ev);
unsigned int cmd_write (const char *str, unsigned int count);
wchar_t next_char () NOTHROW;
int
SET_FGCOLOR (int rend, int new_color)
CODE:
- RETVAL = SET_FGCOLOR (rend, new_color);
+ RETVAL = SET_FGCOLOR (rend, clamp (new_color, 0, TOTAL_COLORS - 1));
OUTPUT:
RETVAL
int
SET_BGCOLOR (int rend, int new_color)
CODE:
- RETVAL = SET_BGCOLOR (rend, new_color);
+ RETVAL = SET_BGCOLOR (rend, clamp (new_color, 0, TOTAL_COLORS - 1));
OUTPUT:
RETVAL
rxvt_term::focus_out ()
void
+rxvt_term::key_press (unsigned int state, unsigned int keycode, Time time = CurrentTime)
+ ALIAS:
+ key_release = 1
+ CODE:
+{
+ XKeyEvent xkey;
+
+ memset (&xkey, 0, sizeof (xkey));
+
+ xkey.time = time;
+ xkey.state = state;
+ xkey.keycode = keycode;
+
+ xkey.type = ix ? KeyRelease : KeyPress;
+ xkey.display = THIS->dpy;
+ xkey.window = THIS->vt;
+ xkey.root = THIS->display->root;
+ xkey.subwindow = THIS->vt;
+
+ if (ix)
+ THIS->key_release (xkey);
+ else
+ THIS->key_press (xkey);
+}
+
+void
rxvt_term::want_refresh ()
CODE:
THIS->want_refresh = 1;
B<Shift-Right> will switch to the tab left or right of the current one,
while B<Shift-Down> creates a new tab.
+The tabbar itself can be configured similarly to a normal terminal, but
+with a resource class of C<URxvt.tabbed>. In addition, it supports the
+following four resources (shown with defaults):
+
+ URxvt.tabbed.tabbar-fg: <colour-index, default 3>
+ URxvt.tabbed.tabbar-bg: <colour-index, default 0>
+ URxvt.tabbed.tab-fg: <colour-index, default 0>
+ URxvt.tabbed.tab-bg: <colour-index, default 1>
+
+See I<COLOR AND GRAPHICS> in the @@RXVT_NAME@@(1) manpage for valid
+indices.
+
=item mark-urls
Uses per-line display filtering (C<on_line_update>) to underline urls and
=item $rend = urxvt::SET_BGCOLOR $rend, $new_colour
+=item $rend = urxvt::SET_COLOR $rend, $new_fg, $new_bg
+
Replace the foreground/background colour in the rendition mask with the
specified one.
$retval
}
+sub SET_COLOR($$$) {
+ SET_BGCOLOR (SET_FGCOLOR ($_[0], $_[1]), $_[2])
+}
+
# urxvt::term::extension
package urxvt::term::extension;
$term->vt_emask_add (urxvt::PointerMotionMask);
+=item $term->focus_in
+
+=item $term->focus_out
+
+=item $term->key_press ($state, $keycode[, $time])
+
+=item $term->key_release ($state, $keycode[, $time])
+
+Deliver various fake events to to terminal.
+
=item $window_width = $term->width
=item $window_height = $term->height