diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 878ca5950fc5d5904290d65a1c638cb2fd9aa5ce..719b0dbfb0cbecea957be2fd0d0436c891165576 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -136,7 +136,10 @@ test:
     - build_meson
   script:
     - apt-get -y build-dep .
+    - apt-get -y install clang-tidy
     - ninja -C _build test
+    - cd _build
+    - clang-tidy --checks=-clang-diagnostic-missing-braces,readability-braces-around-statements, --warnings-as-errors=readability-braces-around-statements -extra-arg=-Wno-unknown-warning-option ../src/*.c ../eek/*.c ../eekboard/*.c
 
 check_release:
   <<: *tags
diff --git a/doc/hacking.md b/doc/hacking.md
index d8c378113b2586daaf090df1f63949cb0f8c5934..5417a1b6b0491cecf254a708e409e3a457d10263 100644
--- a/doc/hacking.md
+++ b/doc/hacking.md
@@ -113,7 +113,7 @@ User interface modules should:
 
 Code submitted should roughly match the style of surrounding code. Things that will *not* be accepted are ones that often lead to errors:
 
-- skipping brackets `{}` after every `if()`, `else`, and similar
+- skipping brackets `{}` after every `if()`, `else`, and similar ([SCI CERT C: EXP19-C](https://wiki.sei.cmu.edu/confluence/display/c/EXP19-C.+Use+braces+for+the+body+of+an+if%2C+for%2C+or+while+statement))
 
 Bad example:
 
diff --git a/eek/eek-gtk-keyboard.c b/eek/eek-gtk-keyboard.c
index cdf0571d4078edb4bd1ac01c5a216ff89ec7b7d1..071d07034c5917f991f59dafa4adb55c6c273f63 100644
--- a/eek/eek-gtk-keyboard.c
+++ b/eek/eek-gtk-keyboard.c
@@ -129,11 +129,12 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget     *self,
         eekboard_context_service_use_layout(priv->eekboard_context, priv->layout, time);
     }
 
-    if (priv->renderer)
+    if (priv->renderer) {
         eek_renderer_set_allocation_size (priv->renderer,
                                           priv->keyboard->layout,
                                           allocation->width,
                                           allocation->height);
+    }
 
     GTK_WIDGET_CLASS (eek_gtk_keyboard_parent_class)->
         size_allocate (self, allocation);
@@ -355,10 +356,11 @@ eek_gtk_keyboard_init (EekGtkKeyboard *self)
     EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
     g_autoptr(GError) err = NULL;
 
-    if (lfb_init(SQUEEKBOARD_APP_ID, &err))
+    if (lfb_init(SQUEEKBOARD_APP_ID, &err)) {
         priv->event = lfb_event_new ("button-pressed");
-    else
+    } else {
         g_warning ("Failed to init libfeedback: %s", err->message);
+    }
 
     GtkIconTheme *theme = gtk_icon_theme_get_default ();
 
diff --git a/eek/eek-keyboard.c b/eek/eek-keyboard.c
index 3295da2dd3701d5524dd1eb35e37eba323582c8c..a7e97357988fbf9457c7238cb77ea481f4548408 100644
--- a/eek/eek-keyboard.c
+++ b/eek/eek-keyboard.c
@@ -42,8 +42,9 @@ struct keymap squeek_key_map_from_str(const char *keymap_str) {
     struct xkb_keymap *keymap = xkb_keymap_new_from_string(context, keymap_str,
         XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
 
-    if (!keymap)
+    if (!keymap) {
         g_error("Bad keymap:\n%s", keymap_str);
+    }
 
     xkb_context_unref(context);
 
@@ -52,8 +53,9 @@ struct keymap squeek_key_map_from_str(const char *keymap_str) {
 
     g_autofree char *path = strdup("/eek_keymap-XXXXXX");
     char *r = &path[strlen(path) - 6];
-    if (getrandom(r, 6, GRND_NONBLOCK) < 0)
+    if (getrandom(r, 6, GRND_NONBLOCK) < 0) {
         g_error("Failed to get random numbers: %s", strerror(errno));
+    }
     for (unsigned i = 0; i < 6; i++) {
         r[i] = (r[i] & 0b1111111) | 0b1000000; // A-z
         r[i] = r[i] > 'z' ? '?' : r[i]; // The randomizer doesn't need to be good...
diff --git a/eek/layersurface.c b/eek/layersurface.c
index f74b6bfab9e6885d867fc26c44a64c703c2a795e..bc2c325f7e62e780f81798ff67275ea8b373a848 100644
--- a/eek/layersurface.c
+++ b/eek/layersurface.c
@@ -590,27 +590,32 @@ phosh_layer_surface_set_size(PhoshLayerSurface *self, gint width, gint height)
   g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
   priv = phosh_layer_surface_get_instance_private (self);
 
-  if (priv->height == height && priv->width == width)
+  if (priv->height == height && priv->width == width) {
     return;
+  }
 
   old_width = priv->width;
   old_height = priv->height;
 
-  if (width != -1)
+  if (width != -1) {
     priv->width = width;
+  }
 
-  if (height != -1)
+  if (height != -1) {
     priv->height = height;
+  }
 
   if (gtk_widget_get_mapped (GTK_WIDGET (self))) {
     zwlr_layer_surface_v1_set_size(priv->layer_surface, priv->width, priv->height);
   }
 
-  if (priv->height != old_height)
+  if (priv->height != old_height) {
     g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT]);
+  }
 
-  if (priv->width != old_width)
+  if (priv->width != old_width) {
     g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH]);
+  }
 }
 
 /**
@@ -632,25 +637,31 @@ phosh_layer_surface_set_margins(PhoshLayerSurface *self, gint top, gint right, g
   old_right = priv->margin_right;
   old_bottom = priv->margin_bottom;
 
-  if (old_top == top && old_left == left && old_right == right && old_bottom == bottom)
+  if (old_top == top && old_left == left && old_right == right && old_bottom == bottom) {
     return;
+  }
 
   priv->margin_top = top;
   priv->margin_left = left;
   priv->margin_right = right;
   priv->margin_bottom = bottom;
 
-  if (priv->layer_surface)
+  if (priv->layer_surface) {
     zwlr_layer_surface_v1_set_margin(priv->layer_surface, top, right, bottom, left);
+  }
 
-  if (old_top != top)
+  if (old_top != top) {
     g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_MARGIN_TOP]);
-  if (old_bottom != bottom)
+  }
+  if (old_bottom != bottom) {
     g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_MARGIN_BOTTOM]);
-  if (old_left != left)
+  }
+  if (old_left != left) {
     g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_MARGIN_LEFT]);
-  if (old_right != right)
+  }
+  if (old_right != right) {
     g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_MARGIN_RIGHT]);
+  }
 }
 
 /**
@@ -669,13 +680,15 @@ phosh_layer_surface_set_exclusive_zone(PhoshLayerSurface *self, gint zone)
 
   old_zone = priv->exclusive_zone;
 
-  if (old_zone == zone)
+  if (old_zone == zone) {
     return;
+  }
 
   priv->exclusive_zone = zone;
 
-  if (priv->layer_surface)
+  if (priv->layer_surface) {
     zwlr_layer_surface_v1_set_exclusive_zone(priv->layer_surface, zone);
+  }
 
   g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_EXCLUSIVE_ZONE]);
 }
@@ -693,13 +706,14 @@ phosh_layer_surface_set_kbd_interactivity (PhoshLayerSurface *self, gboolean int
   g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
   priv = phosh_layer_surface_get_instance_private (self);
 
-    if (priv->kbd_interactivity == interactivity)
+  if (priv->kbd_interactivity == interactivity) {
     return;
-
+  }
   priv->kbd_interactivity = interactivity;
 
-  if (priv->layer_surface)
+  if (priv->layer_surface) {
     zwlr_layer_surface_v1_set_keyboard_interactivity (priv->layer_surface, interactivity);
+  }
 
   g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_KBD_INTERACTIVITY]);
 }
@@ -717,6 +731,7 @@ phosh_layer_surface_wl_surface_commit (PhoshLayerSurface *self)
   g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
   priv = phosh_layer_surface_get_instance_private (self);
 
-  if (priv->wl_surface)
+  if (priv->wl_surface) {
     wl_surface_commit (priv->wl_surface);
+  }
 }
diff --git a/meson.build b/meson.build
index a7b105015b02cf6742f33ebe9c2828026956dfc1..40b6e8f0f04ca9c19856f84a89a7866f8dd42d67 100644
--- a/meson.build
+++ b/meson.build
@@ -20,6 +20,7 @@ add_project_arguments(
     '-Werror=incompatible-pointer-types',
     '-Werror=int-conversion',
     '-Werror=redundant-decls',
+    '-Werror=parentheses',
     '-Wformat-nonliteral',
     '-Wformat-security',
     '-Winit-self',
diff --git a/src/server-context-service.c b/src/server-context-service.c
index 0018e7726acee2f17709a34c05a6c75493ffbab5..3a365c33b8efb92c7a5fb30cb8af62a53b647cce 100644
--- a/src/server-context-service.c
+++ b/src/server-context-service.c
@@ -125,14 +125,17 @@ on_surface_configure(ServerContextService *self, PhoshLayerSurface *surface)
     // we can use different algorithms for portrait and landscape mode.
     // Note: this is a temporary fix until the size manager is complete.
     display = gdk_display_get_default ();
-    if (display)
+    if (display) {
         window = gtk_widget_get_window (GTK_WIDGET (surface));
-    if (window)
+    }
+    if (window) {
         monitor = gdk_display_get_monitor_at_window (display, window);
-    if (monitor)
+    }
+    if (monitor) {
         gdk_monitor_get_geometry (monitor, &geometry);
-    else
+    } else {
         geometry.width = geometry.height = 0;
+    }
 
      // When the geometry event comes after surface.configure,
      // this entire height calculation does nothing.
@@ -159,8 +162,9 @@ on_surface_configure(ServerContextService *self, PhoshLayerSurface *surface)
 static void
 make_window (ServerContextService *self)
 {
-    if (self->window)
+    if (self->window) {
         g_error("Window already present");
+    }
 
     struct squeek_output_handle output = squeek_outputs_get_current(squeek_wayland->outputs);
     squeek_uiman_set_output(self->manager, output);
@@ -234,19 +238,21 @@ on_hide (ServerContextService *self)
 static void
 server_context_service_real_show_keyboard (ServerContextService *self)
 {
-    if (!self->enabled)
+    if (!self->enabled) {
         return;
+    }
 
     if (self->hiding) {
 	    g_source_remove (self->hiding);
 	    self->hiding = 0;
     }
 
-    if (!self->window)
+    if (!self->window) {
         make_window (self);
-    if (!self->widget)
+    }
+    if (!self->widget) {
         make_widget (self);
-
+    }
     self->visible = TRUE;
     gtk_widget_show (GTK_WIDGET(self->window));
 }
@@ -254,9 +260,9 @@ server_context_service_real_show_keyboard (ServerContextService *self)
 static void
 server_context_service_real_hide_keyboard (ServerContextService *self)
 {
-    if (!self->hiding)
+    if (!self->hiding) {
         self->hiding = g_timeout_add (200, (GSourceFunc) on_hide, self);
-
+    }
     self->visible = FALSE;
 }
 
@@ -404,13 +410,8 @@ void
 server_context_service_set_enabled (ServerContextService *self, gboolean enabled)
 {
     g_return_if_fail (SERVER_IS_CONTEXT_SERVICE (self));
-
-    if (enabled == self->enabled)
-        return;
-
     self->enabled = enabled;
-    if (self->enabled)
-        server_context_service_show_keyboard (self);
-    else
+    if (!self->enabled) {
         server_context_service_hide_keyboard (self);
+    }
 }
diff --git a/src/server-main.c b/src/server-main.c
index f3f5edb81fffbb471c5265191390bbe44a7a8f87..6149df5bc87311148a2e2109d3e7a8c790707f08 100644
--- a/src/server-main.c
+++ b/src/server-main.c
@@ -213,12 +213,13 @@ main (int argc, char **argv)
     // dbus is not strictly necessary for the useful operation
     // if text-input is used, as it can bring the keyboard in and out
     GBusType bus_type;
-    if (opt_system)
+    if (opt_system) {
         bus_type = G_BUS_TYPE_SYSTEM;
-    else if (opt_address)
+    } else if (opt_address) {
         bus_type = G_BUS_TYPE_NONE;
-    else
+    } else {
         bus_type = G_BUS_TYPE_SESSION;
+    }
 
     GDBusConnection *connection = NULL;
     GError *error = NULL;