wez / wezterm

A GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust
https://wezfurlong.org/wezterm/
Other
15.21k stars 684 forks source link

Hanging after recent update on Arch #5197

Open Anakael opened 4 months ago

Anakael commented 4 months ago

What Operating System(s) are you seeing this problem on?

Linux Wayland

Which Wayland compositor or X11 Window manager(s) are you using?

Hyprland

WezTerm version

20240316-074238-889f8a9c

Did you try the latest nightly build to see if the issue is better (or worse!) than your current version?

Yes, and I updated the version box above to show the version of the nightly that I tried

Describe the bug

After running wezterm it's just hanging. image

To Reproduce

No response

Configuration

The same behavior with running wezterm -n

Expected Behavior

Make it works again!

Logs

22:42:16.231  DEBUG  config > Reloaded configuration! generation=1
22:42:16.232  DEBUG  window::os::wayland::inputhandler > created ZwpTextInputV3 35 1
22:42:16.232  DEBUG  window::os::x_and_wayland         > Using wayland connection!
22:42:16.262  DEBUG  config                            > Reloaded configuration! generation=2
22:42:16.272  DEBUG  wezterm_gui::frontend             > workspace is default, fixup windows
22:42:16.282  DEBUG  wezterm_font::ftwrap              > set_char_size computing 15 dpi=96 (pixel height=20)
22:42:16.282  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Mode(SetDecPrivateMode(Code(BracketedPaste))))
22:42:16.282  DEBUG  wezterm_term::terminalstate::performer > perform OperatingSystemCommand(CurrentWorkingDirectory("file://archlinux/home/dmitry"))
22:42:16.283  DEBUG  window::os::wayland::output            > zwlr_head_info: {}
22:42:16.284  DEBUG  window::os::wayland::window            > Config: self.window_state=None, states:(empty) []
22:42:16.284  DEBUG  window::os::wayland::window            > dispatch_pending_event self.window_state=(empty) pending:(empty)
22:42:16.284  DEBUG  wezterm_gui::termwindow                > Resized { dimensions: Dimensions { pixel_width: 960, pixel_height: 1066, dpi: 96 }, window_state: (empty), live_resizing: false }
22:42:16.284  DEBUG  wezterm_term::screen                   > resize screen to 80x39 dpi=96
22:42:16.284  DEBUG  wezterm_term::screen                   > resize screen to 80x39 dpi=96
22:42:16.284  DEBUG  wezterm_gui::termwindow                > NeedRepaint
22:42:16.287  DEBUG  wezterm_term::terminalstate::performer > perform OperatingSystemCommand(SetIconNameAndWindowTitle("~"))
22:42:16.287  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Sgr(Foreground(PaletteIndex(0))))
22:42:16.287  DEBUG  wezterm_term::terminalstate            > Foreground(PaletteIndex(0))
22:42:16.287  DEBUG  wezterm_term::terminalstate::performer > perform Esc(Code(AsciiCharacterSetG0))
22:42:16.287  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Sgr(Reset))
22:42:16.287  DEBUG  wezterm_term::terminalstate            > Reset
22:42:16.287  DEBUG  wezterm_term::terminalstate::performer > perform Control(CarriageReturn)
22:42:16.287  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Edit(EraseInDisplay(EraseToEndOfDisplay)))
22:42:16.287  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Edit(EraseInLine(EraseToEndOfLine)))
22:42:16.287  DEBUG  wezterm_term::terminalstate::performer > perform Control(CarriageReturn)
22:42:16.287  DEBUG  wezterm_term::terminalstate::performer > perform Control(LineFeed)
22:42:16.287  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Sgr(Intensity(Bold)))
22:42:16.288  DEBUG  wezterm_term::terminalstate            > Intensity(Bold)
22:42:16.288  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Sgr(Foreground(PaletteIndex(6))))
22:42:16.288  DEBUG  wezterm_term::terminalstate            > Foreground(PaletteIndex(6))
22:42:16.288  DEBUG  wezterm_term::terminalstate::performer > perform Print('~')
22:42:16.288  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Sgr(Reset))
22:42:16.288  DEBUG  wezterm_term::terminalstate            > Reset
22:42:16.288  DEBUG  wezterm_term::terminalstate::performer > perform Print(' ')
22:42:16.288  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Edit(EraseInLine(EraseToEndOfLine)))
22:42:16.288  DEBUG  wezterm_term::terminalstate::performer > perform Control(CarriageReturn)
22:42:16.288  DEBUG  wezterm_term::terminalstate::performer > perform Control(LineFeed)
22:42:16.288  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Sgr(Intensity(Bold)))
22:42:16.288  DEBUG  wezterm_term::terminalstate            > Intensity(Bold)
22:42:16.288  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Sgr(Foreground(PaletteIndex(2))))
22:42:16.288  DEBUG  wezterm_term::terminalstate            > Foreground(PaletteIndex(2))
22:42:16.288  DEBUG  wezterm_term::terminalstate::performer > perform Print('❯')
22:42:16.288  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Sgr(Reset))
22:42:16.288  DEBUG  wezterm_term::terminalstate            > Reset
22:42:16.288  DEBUG  wezterm_term::terminalstate::performer > perform Print(' ')
22:42:16.288  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Edit(EraseInLine(EraseToEndOfLine)))
22:42:16.288  DEBUG  wezterm_term::terminalstate::performer > perform Control(CarriageReturn)
22:42:16.288  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Cursor(Right(1)))
22:42:16.288  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Cursor(Right(1)))
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform OperatingSystemCommand(SetIconNameAndWindowTitle("~"))
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Sgr(Foreground(PaletteIndex(0))))
22:42:16.293  DEBUG  wezterm_term::terminalstate            > Foreground(PaletteIndex(0))
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform Esc(Code(AsciiCharacterSetG0))
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Sgr(Reset))
22:42:16.293  DEBUG  wezterm_term::terminalstate            > Reset
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform Control(CarriageReturn)
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Cursor(Up(1)))
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Cursor(Up(1)))
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Edit(EraseInDisplay(EraseToEndOfDisplay)))
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Edit(EraseInLine(EraseToEndOfLine)))
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform Control(CarriageReturn)
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform Control(LineFeed)
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Sgr(Intensity(Bold)))
22:42:16.293  DEBUG  wezterm_term::terminalstate            > Intensity(Bold)
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Sgr(Foreground(PaletteIndex(6))))
22:42:16.293  DEBUG  wezterm_term::terminalstate            > Foreground(PaletteIndex(6))
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform Print('~')
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Sgr(Reset))
22:42:16.293  DEBUG  wezterm_term::terminalstate            > Reset
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform Print(' ')
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Edit(EraseInLine(EraseToEndOfLine)))
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform Control(CarriageReturn)
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform Control(LineFeed)
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Sgr(Intensity(Bold)))
22:42:16.293  DEBUG  wezterm_term::terminalstate            > Intensity(Bold)
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Sgr(Foreground(PaletteIndex(2))))
22:42:16.293  DEBUG  wezterm_term::terminalstate            > Foreground(PaletteIndex(2))
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform Print('❯')
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Sgr(Reset))
22:42:16.293  DEBUG  wezterm_term::terminalstate            > Reset
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform Print(' ')
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Edit(EraseInLine(EraseToEndOfLine)))
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform Control(CarriageReturn)
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Cursor(Right(1)))
22:42:16.293  DEBUG  wezterm_term::terminalstate::performer > perform CSI(Cursor(Right(1)))
22:42:16.324  DEBUG  wezterm_gui::termwindow                > OpenGL initialized! OpenGL: AMD Radeon RX 6900 XT (radeonsi, navi21, LLVM 17.0.6, DRM 3.57, 6.8.1-arch1-1) 4.6 (Compatibility Profile) Mesa 24.0.3-arch1.1 wezterm version: 20240203-110809-5046fc22
22:42:16.324  DEBUG  wezterm_gui::frontend                  > workspace is default, fixup windows
22:42:16.325  DEBUG  wezterm_gui::termwindow                > Notification(Any { .. })
22:42:16.325  DEBUG  wezterm_gui::termwindow                > Notification(Any { .. })
22:42:16.325  DEBUG  wezterm_gui::termwindow                > Notification(Any { .. })

Anything else?

strace (not full):

write(13, "x", 1)                       = 1
write(13, "x", 1)                       = 1
write(13, "x", 1)                       = 1
write(13, "x", 1)                       = 1
mmap(NULL, 2101248, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f811ec00000
mprotect(0x7f811ec01000, 2097152, PROT_READ|PROT_WRITE) = 0
rt_sigprocmask(SIG_BLOCK, ~[], [], 8)   = 0
clone3({flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, child_tid=0x7f811ee00990, parent_tid=0x7f811ee00990, exit_signal=0, stack=0x7f811ec00000, stack_size=0x1ffb80, tls=0x7f811ee006c0} => {parent_tid=[26188]}, 88) = 26188
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
write(13, "x", 1)                       = 1
read(12, "xxxxx", 64)                   = 5
epoll_wait(14, [], 8, 0)                = 0
epoll_ctl(4, EPOLL_CTL_MOD, 28, {events=EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLONESHOT, data={u32=1, u64=1}}) = 0
write(13, "x", 1)                       = 1
read(12, "x", 64)                       = 1
epoll_wait(14, [], 8, 0)                = 0
read(12, 0x7ffc2096fdb0, 64)            = -1 EAGAIN (Resource temporarily unavailable)
epoll_wait(14, [], 8, 0)                = 0
write(13, "x", 1)                       = 1
read(12, "x", 64)                       = 1
epoll_wait(14, [], 8, 0)                = 0
write(13, "x", 1)                       = 1
read(12, "x", 64)                       = 1
epoll_wait(14, [], 8, 0)                = 0
write(13, "x", 1)                       = 1
read(12, "x", 64)                       = 1
epoll_wait(14, [], 8, 0)                = 0
read(12, 0x7ffc2096fdb0, 64)            = -1 EAGAIN (Resource temporarily unavailable)
epoll_wait(14, [], 8, 0)                = 0
getpeername(28, {sa_family=AF_UNIX, sun_path="/run/user/1000/bus"}, [110 => 21]) = 0
geteuid()                               = 1000
sendmsg(28, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\0", iov_len=1}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 1
sendmsg(28, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="AUTH EXTERNAL 31303030\r\n", iov_len=24}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 24
recvmsg(28, {msg_name={sa_family=AF_UNIX, sun_path="/run/user/1000/bus"}, msg_namelen=110 => 21, msg_iov=[{iov_base="OK 86f6f55eca06d4a83fa7d269a4377"..., iov_len=64}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 37
sendmsg(28, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="NEGOTIATE_UNIX_FD\r\n", iov_len=19}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 19
recvmsg(28, {msg_name={sa_family=AF_UNIX, sun_path="/run/user/1000/bus"}, msg_namelen=110 => 21, msg_iov=[{iov_base="AGREE_UNIX_FD\r\n", iov_len=64}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 15
sendmsg(28, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="BEGIN\r\n", iov_len=7}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 7
sendmsg(28, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="l\1\0\1\0\0\0\0\1\0\0\0m\0\0\0\1\1o\0\25\0\0\0/org/fre"..., iov_len=128}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 128
recvmsg(28, {msg_namelen=110}, 0)       = -1 EAGAIN (Resource temporarily unavailable)
epoll_ctl(4, EPOLL_CTL_MOD, 28, {events=EPOLLIN|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLRDHUP|EPOLLONESHOT, data={u32=1, u64=1}}) = 0
write(13, "x", 1)                       = 1
read(12, "x", 64)                       = 1
epoll_wait(14, [], 8, 0)                = 0
read(12, 0x7ffc2096fdb0, 64)            = -1 EAGAIN (Resource temporarily unavailable)
epoll_wait(14, [], 8, 0)                = 0
read(12, 0x7ffc2096fdb0, 64)            = -1 EAGAIN (Resource temporarily unavailable)
epoll_wait(14, [], 8, 0)                = 0
read(12, 0x7ffc2096fdb0, 64)            = -1 EAGAIN (Resource temporarily unavailable)
epoll_wait(14, [], 8, 0)                = 0
recvmsg(28, {msg_name={sa_family=AF_UNIX, sun_path="/run/user/1000/bus"}, msg_namelen=110 => 21, msg_iov=[{iov_base="l\2\1\1\n\0\0\0\377\377\377\377?\0\0\0", iov_len=16}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 16
recvmsg(28, {msg_name={sa_family=AF_UNIX, sun_path="/run/user/1000/bus"}, msg_namelen=110 => 21, msg_iov=[{iov_base="\5\1u\0\1\0\0\0\7\1s\0\24\0\0\0org.freedesktop."..., iov_len=74}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 74
recvmsg(28, {msg_name={sa_family=AF_UNIX, sun_path="/run/user/1000/bus"}, msg_namelen=110 => 21, msg_iov=[{iov_base="l\4\1\1\n\0\0\0\377\377\377\377\217\0\0\0", iov_len=16}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 16
recvmsg(28, {msg_name={sa_family=AF_UNIX, sun_path="/run/user/1000/bus"}, msg_namelen=110 => 21, msg_iov=[{iov_base="\7\1s\0\24\0\0\0org.freedesktop.DBus\0\0\0\0"..., iov_len=154}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 154
recvmsg(28, {msg_namelen=110}, 0)       = -1 EAGAIN (Resource temporarily unavailable)
epoll_ctl(4, EPOLL_CTL_MOD, 28, {events=EPOLLIN|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLRDHUP|EPOLLONESHOT, data={u32=1, u64=1}}) = 0
write(13, "x", 1)                       = 1
read(12, "x", 64)                       = 1
epoll_wait(14, [], 8, 0)                = 0
mmap(NULL, 2101248, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f811e800000
mprotect(0x7f811e801000, 2097152, PROT_READ|PROT_WRITE) = 0
rt_sigprocmask(SIG_BLOCK, ~[], [], 8)   = 0
clone3({flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, child_tid=0x7f811ea00990, parent_tid=0x7f811ea00990, exit_signal=0, stack=0x7f811e800000, stack_size=0x1ffb80, tls=0x7f811ea006c0} => {parent_tid=[26189]}, 88) = 26189
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
sendmsg(28, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="l\1\0\0011\0\0\0\2\0\0\0\240\0\0\0\1\1o\0\37\0\0\0/org/fre"..., iov_len=225}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 225
write(5, "\1\0\0\0\0\0\0\0", 8)         = 8
read(12, 0x7ffc2096fdb0, 64)            = -1 EAGAIN (Resource temporarily unavailable)
epoll_wait(14, [{events=EPOLLIN, data={u32=4294967293, u64=4294967293}}], 8, -1) = 1
write(5, "\1\0\0\0\0\0\0\0", 8)         = 8
futex(0x7f810c000c60, FUTEX_WAKE_PRIVATE, 1) = 1
read(12, "x", 64)                       = 1
epoll_wait(14, ^C0x576359061c50, 8, -1)   = -1 EINTR (Interrupted system call)
strace: Process 26107 detached
johnazule commented 4 months ago

Same here, updated my hyprland version and wezterm won't create a window. This issue seems to indicate theres an issue with how wezterm implements the wl protocol https://github.com/hyprwm/Hyprland/issues/4806#issue-2150349755

fioncat commented 4 months ago

You can add config.enable_wayland = false to your config to temporary fix this.

The xorg-xwayland is needed.

ErrorNoInternet commented 4 months ago

Same here, updated my hyprland version and wezterm won't create a window. This issue seems to indicate theres an issue with how wezterm implements the wl protocol hyprwm/Hyprland#4806 (comment)

That (Hyprland link) is a completely different issue. If wezterm is printing anything then it's https://github.com/wez/wezterm/issues/5103, which should only appear on Hyprland 0.37.0 (technically 2 commits after 0.36.0)

JoshElias commented 4 months ago

Also having this issue on Void Linux under Wayland. I'm not running it under xwayland so I'll use the Foot terminal while this is being fixed. I can provide logs if that helps.

JeffDess commented 4 months ago

Also have this issue since last update on two Arch Hyprland machines. enable_wayland = false does allow to launch a window, otherwise nothing shows up.

Here's the log for WAYLAND_DEBUG=1 wezterm start --always-new-process if that could help: wezterm-wayland_2024-03-22-2233.log

JeffDess commented 4 months ago

Well, I think I just found a workaround. WAYLAND_DISPLAY=1 wezterm seems to work fine.

JoshElias commented 4 months ago

Well, I think I just found a workaround. WAYLAND_DISPLAY=1 wezterm seems to work fine.

While this worked for me too, it should be noted that this seems to be equivalent to config.enable_wayland = false by disabling wayland support.

blackthorne7 commented 4 months ago

+1, exact same situation (Arch/hyprland).

I'm downgrading to the previous version of Hyprland meanwhile.

kkk-petrov commented 4 months ago

same

phoeshow commented 4 months ago

disable wayland?so why dont use kitty?

elfenpiff commented 4 months ago

I have the same setup (archlinux, wayland + hyprland) and problem.

But to make things weirder, when I call wezterm from within alacritty it works.

JoshElias commented 4 months ago

I have the same setup (archlinux, wayland + hyprland) and problem.

But to make things weirder, when I call wezterm from within alacritty it works.

Are you sure both aren't running on xwayland?

ErrorNoInternet commented 4 months ago

Here's what's happening:

In Wayland, for an application to show up, it has to receive what's called a "configure event" from the compositor.

(the configure event is also used for example to resize the application)

Hyprland v0.36 (and most other compositors probably) will send 2 configure events when an application starts. The first one has mostly-empty fields (including the size, which is set to 0 0) and the second one has a bit more data (with a proper size).

Apps should open (display their window) as soon as they receive their first configure event.

But sending 2 configure events like that cause some issues on slower computers. Most apps (like foot and firefox) will open with a random size (or a very small size) when they're told to open with a size of 0. They will then resize themselves again (second configure event) a few (possibly hundred or thousands) milliseconds later, which will cause tiny visual artifacts.

To fix this, vaxry made it so that Hyprland v0.37 (technically 2 commits after 0.36) will properly predict the size of new apps before they open and send them a single configure event with the right size.

But for some reason, wezterm will only open if it receives a configure event with size 0 0. If you send it a configure event with any other size (e.g. the size it's supposed to open with), it will not display its window.

However, if you open a floating window in the same workspace, you actually "bypass" Hyprland's size predictions for any other new windows (including tiled). Causing Hyprland to send 2 configure events (just like on v0.36); one with size 0 0, and another with the proper size. This makes wezterm show its window again.

Launching wezterm with the floating windowrule will also bypass Hyprland's size predictions.

hy3 (Hyprland plugin for manual tiling) has not implemented size predictions yet, so wezterm also work there.

I'm not very familiar with wezterm's codebase so I am unable to find out how wezterm is expecting an empty configure event, so I just completely removed it as a temporary workaround (nix run github:ErrorNoInternet/configuration.nix#wezterm).

dylantompkins commented 4 months ago

duplicate of #5067

AidanNotFunny commented 3 months ago

Will this be fixed? The terminal looks really ugly for me under XWayland (I use fractional scaling).

realth000 commented 3 months ago

Same here, and set enable_wayland to false will avoid this. Also occurs with the latest revision e5ac32f.

Reset enable_wayland to true will not effect already launched wezterm, they acts without error.

raffaem commented 1 month ago

Is this a duplicate of #5103 ?