Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13216236
D18669.id44823.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Referenced Files
None
Subscribers
None
D18669.id44823.diff
View Options
diff --git a/scripts/__init_script__.php b/scripts/__init_script__.php
--- a/scripts/__init_script__.php
+++ b/scripts/__init_script__.php
@@ -90,6 +90,9 @@
$handler = new PhutilBacktraceSignalHandler();
$router->installHandler('phutil.backtrace', $handler);
+
+ $handler = new PhutilConsoleMetricsSignalHandler();
+ $router->installHandler('phutil.winch', $handler);
}
__phutil_init_script__();
diff --git a/scripts/test/progress_bar.php b/scripts/test/progress_bar.php
--- a/scripts/test/progress_bar.php
+++ b/scripts/test/progress_bar.php
@@ -43,6 +43,19 @@
echo pht('Caught exception!')."\n";
}
+echo "\n".pht(
+ "RESIZING BARS\n".
+ "If you resize the window while a progress bars draws, it should more or ".
+ "less detect the change.");
+
+$n = 1024;
+$bar = id(new PhutilConsoleProgressBar())
+ ->setTotal($n);
+for ($ii = 0; $ii < $n; $ii++) {
+ $bar->update(1);
+ usleep(10000);
+}
+$bar->done();
function run_interrupt_bar() {
$bar = id(new PhutilConsoleProgressBar())
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -177,6 +177,8 @@
'PhutilConsoleList' => 'console/view/PhutilConsoleList.php',
'PhutilConsoleLogLine' => 'console/view/PhutilConsoleLogLine.php',
'PhutilConsoleMessage' => 'console/PhutilConsoleMessage.php',
+ 'PhutilConsoleMetrics' => 'console/PhutilConsoleMetrics.php',
+ 'PhutilConsoleMetricsSignalHandler' => 'future/exec/PhutilConsoleMetricsSignalHandler.php',
'PhutilConsoleProgressBar' => 'console/PhutilConsoleProgressBar.php',
'PhutilConsoleServer' => 'console/PhutilConsoleServer.php',
'PhutilConsoleServerChannel' => 'console/PhutilConsoleServerChannel.php',
@@ -799,6 +801,8 @@
'PhutilConsoleList' => 'PhutilConsoleView',
'PhutilConsoleLogLine' => 'PhutilConsoleView',
'PhutilConsoleMessage' => 'Phobject',
+ 'PhutilConsoleMetrics' => 'Phobject',
+ 'PhutilConsoleMetricsSignalHandler' => 'PhutilSignalHandler',
'PhutilConsoleProgressBar' => 'Phobject',
'PhutilConsoleServer' => 'Phobject',
'PhutilConsoleServerChannel' => 'PhutilChannelChannel',
diff --git a/src/console/PhutilConsoleMetrics.php b/src/console/PhutilConsoleMetrics.php
new file mode 100644
--- /dev/null
+++ b/src/console/PhutilConsoleMetrics.php
@@ -0,0 +1,62 @@
+<?php
+
+final class PhutilConsoleMetrics extends Phobject {
+
+ const DEFAULT_CONSOLE = 'default';
+
+ private static $consoles = array();
+
+ private $width = false;
+
+ public static function getNamedConsole($key) {
+ if (!isset(self::$consoles[$key])) {
+ self::$consoles[$key] = new self();
+ }
+
+ return self::$consoles[$key];
+ }
+
+ public static function getDefaultConsole() {
+ return self::getNamedConsole(self::DEFAULT_CONSOLE);
+ }
+
+ public function didGetWINCHSignal() {
+ // When we receive a "WINCH" ("WINdow CHange") signal, clear the cached
+ // information we have about the terminal.
+ $this->width = false;
+
+ return $this;
+ }
+
+ public function getTerminalWidth() {
+ if ($this->width === false) {
+ $this->width = $this->computeTerminalWidth();
+ }
+
+ return $this->width;
+ }
+
+ private function computeTerminalWidth() {
+ if (phutil_is_windows()) {
+ // TODO: Figure out how to do this on Windows.
+ return null;
+ }
+
+ $tmp = new TempFile();
+ $err = id(new PhutilExecPassthru('tput cols > %s', $tmp))
+ ->resolve();
+ $stdout = Filesystem::readFile($tmp);
+ unset($tmp);
+
+ if ($err) {
+ return null;
+ }
+
+ $width = (int)trim($stdout);
+ if ($width > 0) {
+ return $width;
+ }
+
+ return null;
+ }
+}
diff --git a/src/console/format.php b/src/console/format.php
--- a/src/console/format.php
+++ b/src/console/format.php
@@ -204,35 +204,6 @@
* @return int|null Terminal width in characters, or null on failure.
*/
function phutil_console_get_terminal_width() {
- static $width;
-
- if ($width === null) {
- if (phutil_is_windows()) {
- // TODO: Figure out how to get this working in Windows.
- return null;
- }
-
- $tmp = new TempFile();
-
- // NOTE: We can't just execute this because it won't be connected to a TTY
- // if we do.
- $err = phutil_passthru('tput cols > %s', $tmp);
-
- if ($err) {
- return null;
- }
-
- try {
- $cols = Filesystem::readFile($tmp);
- } catch (FilesystemException $ex) {
- return null;
- }
-
- $width = (int)$cols;
- if (!$width) {
- $width = null;
- }
- }
-
- return $width;
+ return PhutilConsoleMetrics::getDefaultConsole()
+ ->getTerminalWidth();
}
diff --git a/src/future/exec/PhutilConsoleMetricsSignalHandler.php b/src/future/exec/PhutilConsoleMetricsSignalHandler.php
new file mode 100644
--- /dev/null
+++ b/src/future/exec/PhutilConsoleMetricsSignalHandler.php
@@ -0,0 +1,14 @@
+<?php
+
+final class PhutilConsoleMetricsSignalHandler extends PhutilSignalHandler {
+
+ public function canHandleSignal(PhutilSignalRouter $router, $signo) {
+ return ($signo === SIGWINCH);
+ }
+
+ public function handleSignal(PhutilSignalRouter $router, $signo) {
+ PhutilConsoleMetrics::getDefaultConsole()
+ ->didGetWINCHSignal();
+ }
+
+}
diff --git a/src/future/exec/PhutilSignalRouter.php b/src/future/exec/PhutilSignalRouter.php
--- a/src/future/exec/PhutilSignalRouter.php
+++ b/src/future/exec/PhutilSignalRouter.php
@@ -18,6 +18,7 @@
if (function_exists('pcntl_signal')) {
pcntl_signal(SIGHUP, array($router, 'routeSignal'));
pcntl_signal(SIGTERM, array($router, 'routeSignal'));
+ pcntl_signal(SIGWINCH, array($router, 'routeSignal'));
}
self::$router = $router;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, May 18, 11:20 PM (2 w, 1 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6301363
Default Alt Text
D18669.id44823.diff (5 KB)
Attached To
Mode
D18669: Properly cache terminal width and dirty on SIGWINCH
Attached
Detach File
Event Timeline
Log In to Comment