1 /*
2 * RClientMetrics.cpp
3 *
4 * Copyright (C) 2021 by RStudio, PBC
5 *
6 * Unless you have received this program directly from RStudio pursuant
7 * to the terms of a commercial license agreement with RStudio, then
8 * this program is licensed to you under the terms of version 3 of the
9 * GNU Affero General Public License. This program is distributed WITHOUT
10 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
12 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
13 *
14 */
15
16 #include "RClientMetrics.hpp"
17
18 #include <iostream>
19
20 #include <core/Settings.hpp>
21
22 #include <r/ROptions.hpp>
23 #include <r/session/RSession.hpp>
24
25 #include "graphics/RGraphicsDevice.hpp"
26
27 using namespace rstudio::core;
28
29 namespace rstudio {
30 namespace r {
31 namespace session {
32 namespace client_metrics {
33
34 namespace {
35 const char * const kConsoleWidth = "r.session.client_metrics.console-width";
36 const char * const kBuildConsoleWidth = "r.session.client_metrics.build-console-width";
37 const char * const kGraphicsWidth = "r.session.client_metrics.graphics-width";
38 const char * const kGraphicsHeight = "r.session.client_metrics.graphics-height";
39 const char * const kDevicePixelRatio = "r.session.client_metrics.device-pixel-ratio";
40
41 }
42
get()43 RClientMetrics get()
44 {
45 RClientMetrics metrics;
46 metrics.consoleWidth = r::options::getOptionWidth();
47 metrics.buildConsoleWidth = r::options::getBuildOptionWidth();
48 metrics.graphicsWidth = graphics::device::getWidth();
49 metrics.graphicsHeight = graphics::device::getHeight();
50 metrics.devicePixelRatio = graphics::device::devicePixelRatio();
51 return metrics;
52 }
53
set(const RClientMetrics & metrics)54 void set(const RClientMetrics& metrics)
55 {
56 // set console width (if it's within the valid range -- if it's not
57 // then an error will be thrown)
58 if (metrics.consoleWidth >= 10 && metrics.consoleWidth <= 10000)
59 r::options::setOptionWidth(metrics.consoleWidth);
60 if (metrics.buildConsoleWidth >= 10 && metrics.buildConsoleWidth <= 10000)
61 r::options::setBuildOptionWidth(metrics.buildConsoleWidth);
62
63 // set graphics size, however don't do anything if width or height is less
64 // than or equal to 0)
65 // (means the graphics window is minimized)
66 if (metrics.graphicsWidth > 0 && metrics.graphicsHeight > 0)
67 {
68 // enforce a minimum graphics size so we don't get display
69 // list redraw errors -- note that setting the device to a size
70 // which diverges from the actual client size will break locator
71 // so we need to set the size small enough that there is no way
72 // it can reasonably be used for locator
73 int width = std::max(metrics.graphicsWidth, 100);
74 int height = std::max(metrics.graphicsHeight, 100);
75
76 // enforce a maximum graphics size so we don't create a device
77 // that is so large that it exhausts available memory
78 width = std::min(width, 10000);
79 height = std::min(height, 10000);
80
81 // set device size
82 graphics::device::setSize(width, height, metrics.devicePixelRatio);
83 }
84 }
85
save(Settings * pSettings)86 void save(Settings* pSettings)
87 {
88 // get the client metrics
89 RClientMetrics metrics = client_metrics::get();
90
91 // save them
92 pSettings->beginUpdate();
93 pSettings->set(kConsoleWidth, metrics.consoleWidth);
94 pSettings->set(kBuildConsoleWidth, metrics.buildConsoleWidth);
95 pSettings->set(kGraphicsWidth, metrics.graphicsWidth);
96 pSettings->set(kGraphicsHeight, metrics.graphicsHeight);
97 pSettings->set(kDevicePixelRatio, metrics.devicePixelRatio);
98 pSettings->endUpdate();
99 }
100
restore(const Settings & settings)101 void restore(const Settings& settings)
102 {
103 // read the client metrics (specify defaults to be defensive)
104 RClientMetrics metrics;
105 metrics.consoleWidth = settings.getInt(kConsoleWidth,
106 r::options::kDefaultWidth);
107 metrics.buildConsoleWidth = settings.getInt(kBuildConsoleWidth,
108 r::options::kDefaultWidth);
109 metrics.graphicsWidth = settings.getInt(kGraphicsWidth,
110 graphics::device::kDefaultWidth);
111
112 metrics.graphicsHeight = settings.getInt(kGraphicsHeight,
113 graphics::device::kDefaultHeight);
114 metrics.devicePixelRatio = settings.getDouble(kDevicePixelRatio,
115 graphics::device::kDefaultDevicePixelRatio);
116
117 // set them
118 set(metrics);
119 }
120
121
122 } // namespace client_metrics
123 } // namespace session
124 } // namespace r
125 } // namespace rstudio
126
127
128
129