Global Metrics
path: .metrics.loc.ploc
old: 85.0
new: 152.0
path: .metrics.loc.cloc
old: 27.0
new: 18.0
path: .metrics.loc.lloc
old: 12.0
new: 48.0
path: .metrics.loc.sloc
old: 133.0
new: 195.0
path: .metrics.loc.blank
old: 21.0
new: 25.0
path: .metrics.nom.functions
old: 6.0
new: 9.0
path: .metrics.nom.total
old: 6.0
new: 9.0
path: .metrics.mi.mi_original
old: 51.93901821324039
new: 36.0724806458893
path: .metrics.mi.mi_sei
old: 32.07877219675028
new: 1.1535195012840838
path: .metrics.mi.mi_visual_studio
old: 30.373694861544088
new: 21.09501792157269
path: .metrics.cognitive.average
old: 0.0
new: 1.1111111111111112
path: .metrics.cognitive.sum
old: 0.0
new: 10.0
path: .metrics.cyclomatic.sum
old: 7.0
new: 21.0
path: .metrics.cyclomatic.average
old: 1.0
new: 1.75
path: .metrics.halstead.time
old: 1035.8891933524164
new: 9996.565240784055
path: .metrics.halstead.length
old: 256.0
new: 731.0
path: .metrics.halstead.volume
old: 1558.3904873600868
new: 5384.781538613692
path: .metrics.halstead.N2
old: 124.0
new: 327.0
path: .metrics.halstead.effort
old: 18646.005480343498
new: 179938.17433411302
path: .metrics.halstead.N1
old: 132.0
new: 404.0
path: .metrics.halstead.vocabulary
old: 68.0
new: 165.0
path: .metrics.halstead.purity_ratio
old: 1.4473768695796896
new: 1.5144135884859165
path: .metrics.halstead.difficulty
old: 11.964912280701755
new: 33.416058394160586
path: .metrics.halstead.n2
old: 57.0
new: 137.0
path: .metrics.halstead.n1
old: 11.0
new: 28.0
path: .metrics.halstead.level
old: 0.08357771260997067
new: 0.029925731760594144
path: .metrics.halstead.estimated_program_length
old: 370.52847861240053
new: 1107.036333183205
path: .metrics.halstead.bugs
old: 0.23438831142216415
new: 1.0624152234964572
path: .metrics.nexits.average
old: 1.0
new: 0.6666666666666666
path: .metrics.nargs.average
old: 2.3333333333333335
new: 1.2222222222222223
path: .metrics.nargs.sum
old: 14.0
new: 11.0
Spaces Data
Minimal test - lines (24, 195)
path: .spaces[0].metrics.cognitive.average
old: 0.0
new: 1.1111111111111112
path: .spaces[0].metrics.cognitive.sum
old: 0.0
new: 10.0
path: .spaces[0].metrics.halstead.estimated_program_length
old: 72.95445336320968
new: 1055.9843510190187
path: .spaces[0].metrics.halstead.purity_ratio
old: 1.58596637746108
new: 1.460559268352723
path: .spaces[0].metrics.halstead.length
old: 46.0
new: 723.0
path: .spaces[0].metrics.halstead.N1
old: 26.0
new: 404.0
path: .spaces[0].metrics.halstead.difficulty
old: 5.0
new: 34.091603053435115
path: .spaces[0].metrics.halstead.bugs
old: 0.03356034741635397
new: 1.0636407653375493
path: .spaces[0].metrics.halstead.n1
old: 7.0
new: 28.0
path: .spaces[0].metrics.halstead.effort
old: 1010.2330072391148
new: 180249.6137878691
path: .spaces[0].metrics.halstead.vocabulary
old: 21.0
new: 159.0
path: .spaces[0].metrics.halstead.n2
old: 14.0
new: 131.0
path: .spaces[0].metrics.halstead.volume
old: 202.04660144782295
new: 5287.214376670589
path: .spaces[0].metrics.halstead.time
old: 56.1240559577286
new: 10013.867432659395
path: .spaces[0].metrics.halstead.N2
old: 20.0
new: 319.0
path: .spaces[0].metrics.halstead.level
old: 0.2
new: 0.02933273622928795
path: .spaces[0].metrics.mi.mi_visual_studio
old: 61.005792427664645
new: 22.474120525419764
path: .spaces[0].metrics.mi.mi_sei
old: 74.90277755091917
new: 0.025243402639517853
path: .spaces[0].metrics.mi.mi_original
old: 104.31990505130652
new: 38.43074609846779
path: .spaces[0].metrics.nargs.sum
old: 3.0
new: 11.0
path: .spaces[0].metrics.nargs.average
old: 3.0
new: 1.2222222222222223
path: .spaces[0].metrics.nexits.sum
old: 1.0
new: 6.0
path: .spaces[0].metrics.nexits.average
old: 1.0
new: 0.6666666666666666
path: .spaces[0].metrics.cyclomatic.average
old: 1.0
new: 1.818181818181818
path: .spaces[0].metrics.cyclomatic.sum
old: 1.0
new: 20.0
path: .spaces[0].metrics.loc.cloc
old: 0.0
new: 10.0
path: .spaces[0].metrics.loc.blank
old: 0.0
new: 24.0
path: .spaces[0].metrics.loc.sloc
old: 11.0
new: 172.0
path: .spaces[0].metrics.loc.lloc
old: 2.0
new: 48.0
path: .spaces[0].metrics.loc.ploc
old: 11.0
new: 138.0
path: .spaces[0].metrics.nom.total
old: 1.0
new: 9.0
path: .spaces[0].metrics.nom.functions
old: 1.0
new: 9.0
Code
namespace mozilla {
namespace widget {
static LazyLogModule sScreenLog("WidgetScreen");
static void monitors_changed(GdkScreen* aScreen, gpointer aClosure) {
MOZ_LOG(sScreenLog, LogLevel::Debug, ("Received monitors-changed event"));
ScreenHelperGTK* self = static_cast(aClosure);
self->RefreshScreens();
}
static void screen_resolution_changed(GdkScreen* aScreen, GParamSpec* aPspec,
ScreenHelperGTK* self) {
self->RefreshScreens();
}
static GdkFilterReturn root_window_event_filter(GdkXEvent* aGdkXEvent,
GdkEvent* aGdkEvent,
gpointer aClosure) {
#ifdef MOZ_X11
ScreenHelperGTK* self = static_cast(aClosure);
XEvent* xevent = static_cast(aGdkXEvent);
switch (xevent->type) {
case PropertyNotify: {
XPropertyEvent* propertyEvent = &xevent->xproperty;
if (propertyEvent->atom == self->NetWorkareaAtom()) {
MOZ_LOG(sScreenLog, LogLevel::Debug, ("Work area size changed"));
self->RefreshScreens();
}
} break;
default:
break;
}
#endif
return GDK_FILTER_CONTINUE;
}
ScreenHelperGTK::ScreenHelperGTK()
: mRootWindow(nullptr)
#ifdef MOZ_X11
,
mNetWorkareaAtom(0)
#endif
{
MOZ_LOG(sScreenLog, LogLevel::Debug, ("ScreenHelperGTK created"));
GdkScreen* defaultScreen = gdk_screen_get_default();
if (!defaultScreen) {
// Sometimes we don't initial X (e.g., xpcshell)
MOZ_LOG(sScreenLog, LogLevel::Debug,
("defaultScreen is nullptr, running headless"));
return;
}
mRootWindow = gdk_get_default_root_window();
MOZ_ASSERT(mRootWindow);
g_object_ref(mRootWindow);
// GDK_PROPERTY_CHANGE_MASK ==> PropertyChangeMask, for PropertyNotify
gdk_window_set_events(mRootWindow,
GdkEventMask(gdk_window_get_events(mRootWindow) |
GDK_PROPERTY_CHANGE_MASK));
g_signal_connect(defaultScreen, "monitors-changed",
G_CALLBACK(monitors_changed), this);
// Use _after to ensure this callback is run after gfxPlatformGtk.cpp's
// handler.
g_signal_connect_after(defaultScreen, "notify::resolution",
G_CALLBACK(screen_resolution_changed), this);
#ifdef MOZ_X11
gdk_window_add_filter(mRootWindow, root_window_event_filter, this);
if (GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
mNetWorkareaAtom = XInternAtom(GDK_WINDOW_XDISPLAY(mRootWindow),
"_NET_WORKAREA", X11False);
}
#endif
RefreshScreens();
}
ScreenHelperGTK::~ScreenHelperGTK() {
if (mRootWindow) {
g_signal_handlers_disconnect_by_data(gdk_screen_get_default(), this);
gdk_window_remove_filter(mRootWindow, root_window_event_filter, this);
g_object_unref(mRootWindow);
mRootWindow = nullptr;
}
}
gint ScreenHelperGTK::GetGTKMonitorScaleFactor(gint aMonitorNum) {
// Since GDK 3.10
static auto sGdkScreenGetMonitorScaleFactorPtr =
(gint(*)(GdkScreen*, gint))dlsym(RTLD_DEFAULT,
"gdk_screen_get_monitor_scale_factor");
if (sGdkScreenGetMonitorScaleFactorPtr) {
GdkScreen* screen = gdk_screen_get_default();
return sGdkScreenGetMonitorScaleFactorPtr(screen, aMonitorNum);
}
return 1;
}
static uint32_t GetGTKPixelDepth() {
GdkVisual* visual = gdk_screen_get_system_visual(gdk_screen_get_default());
return gdk_visual_get_depth(visual);
}
static already_AddRefed MakeScreen(GdkScreen* aScreen,
gint aMonitorNum) {
GdkRectangle monitor;
GdkRectangle workarea;
gdk_screen_get_monitor_geometry(aScreen, aMonitorNum, &monitor);
gdk_screen_get_monitor_workarea(aScreen, aMonitorNum, &workarea);
gint gdkScaleFactor = ScreenHelperGTK::GetGTKMonitorScaleFactor(aMonitorNum);
// gdk_screen_get_monitor_geometry / workarea returns application pixels
// (desktop pixels), so we need to convert it to device pixels with
// gdkScaleFactor.
LayoutDeviceIntRect rect(
monitor.x * gdkScaleFactor, monitor.y * gdkScaleFactor,
monitor.width * gdkScaleFactor, monitor.height * gdkScaleFactor);
LayoutDeviceIntRect availRect(
workarea.x * gdkScaleFactor, workarea.y * gdkScaleFactor,
workarea.width * gdkScaleFactor, workarea.height * gdkScaleFactor);
uint32_t pixelDepth = GetGTKPixelDepth();
// Use per-monitor scaling factor in gtk/wayland, or 1.0 otherwise.
DesktopToLayoutDeviceScale contentsScale(1.0);
#ifdef MOZ_WAYLAND
GdkDisplay* gdkDisplay = gdk_display_get_default();
if (!GDK_IS_X11_DISPLAY(gdkDisplay)) {
contentsScale.scale = gdkScaleFactor;
}
#endif
CSSToLayoutDeviceScale defaultCssScale(gdkScaleFactor *
gfxPlatformGtk::GetFontScaleFactor());
float dpi = 96.0f;
gint heightMM = gdk_screen_get_monitor_height_mm(aScreen, aMonitorNum);
if (heightMM > 0) {
dpi = rect.height / (heightMM / MM_PER_INCH_FLOAT);
}
MOZ_LOG(sScreenLog, LogLevel::Debug,
("New screen [%d %d %d %d (%d %d %d %d) %d %f %f %f]", rect.x, rect.y,
rect.width, rect.height, availRect.x, availRect.y, availRect.width,
availRect.height, pixelDepth, contentsScale.scale,
defaultCssScale.scale, dpi));
RefPtr screen = new Screen(rect, availRect, pixelDepth, pixelDepth,
contentsScale, defaultCssScale, dpi);
return screen.forget();
}
void ScreenHelperGTK::RefreshScreens() {
MOZ_LOG(sScreenLog, LogLevel::Debug, ("Refreshing screens"));
AutoTArray, 4> screenList;
GdkScreen* defaultScreen = gdk_screen_get_default();
gint numScreens = gdk_screen_get_n_monitors(defaultScreen);
MOZ_LOG(sScreenLog, LogLevel::Debug, ("GDK reports %d screens", numScreens));
for (gint i = 0; i < numScreens; i++) {
screenList.AppendElement(MakeScreen(defaultScreen, i));
}
ScreenManager& screenManager = ScreenManager::GetSingleton();
screenManager.Refresh(std::move(screenList));
}
} // namespace widget
} // namespace mozilla