diff --git a/src/Plugin/UiPatterns/Source/BlockSource.php b/src/Plugin/UiPatterns/Source/BlockSource.php
index 12aa4b8b2ba907aaedd802e1255cca24cfe9f4d7..beaaac3cda9fba4f9faf3a0e029b42b452d5fc12 100644
--- a/src/Plugin/UiPatterns/Source/BlockSource.php
+++ b/src/Plugin/UiPatterns/Source/BlockSource.php
@@ -31,11 +31,10 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
 #[Source(
   id: 'block',
   label: new TranslatableMarkup('Block'),
-  description: new TranslatableMarkup('instantiate a block'),
+  description: new TranslatableMarkup('instantiate a block plugin'),
   prop_types: ['slot']
 )]
 class BlockSource extends SourcePluginBase {
-
   /**
    * Block to be rendered.
    *
@@ -273,14 +272,16 @@ class BlockSource extends SourcePluginBase {
   protected function listBlockDefinitions() : array {
     $context_for_block_discovery = $this->context;
     $definitions = $this->blockManager->getFilteredDefinitions('ui_patterns', $context_for_block_discovery, []);
+    // Filter plugins based on the flag 'ui_patterns_compatibility'.
+    // @see function ui_patterns_plugin_filter_block__ui_patterns_alter
+    // from ui_patterns.module file
+    $definitions = array_filter($definitions, function ($definition, $plugin_id) {
+      return !isset($definition['_ui_patterns_compatible']) || $definition['_ui_patterns_compatible'];
+    }, ARRAY_FILTER_USE_BOTH);
+    // Filter based on contexts.
     $definitions = $this->contextHandler->filterPluginDefinitionsByContexts($context_for_block_discovery, $definitions);
     // Order by category, and then by admin label.
     $definitions = $this->blockManager->getSortedDefinitions($definitions);
-    /*
-    // Filter out definitions that are not intended to be placed by the UI.
-    $definitions = array_filter($definitions, function (array $definition) {
-    return empty($definition['_block_ui_hidden']);
-    });*/
     return $definitions;
   }
 
diff --git a/ui_patterns.module b/ui_patterns.module
index f75c3c9f6595798069b9b3b1ef5a30253e1a3c6b..324fdc4c8727e20c5001310cb90f12dbc8c2a963 100644
--- a/ui_patterns.module
+++ b/ui_patterns.module
@@ -21,9 +21,18 @@ function ui_patterns_element_info_alter(array &$types) {
 }
 
 /**
+ * Prepare list of block plugins returned when using consumer 'ui_patterns'.
+ *
+ * @see \Drupal\ui_patterns\Plugin\UiPatterns\Source\BlockSource::listBlockDefinitions()
+ *
  * Implements hook_plugin_filter_TYPE__CONSUMER_alter().
  */
 function ui_patterns_plugin_filter_block__ui_patterns_alter(array &$definitions, array $extra) {
+  // @todo Determine the 'inline_block' blocks should be allowed outside
+  //   of layout_builder https://www.drupal.org/node/2979142.
+  $definitions = array_filter($definitions, function ($definition) {
+    return $definition['id'] !== 'inline_block';
+  });
   // Remove blocks that are not useful within Layout Builder.
   unset($definitions['system_messages_block']);
   unset($definitions['help_block']);
@@ -33,19 +42,42 @@ function ui_patterns_plugin_filter_block__ui_patterns_alter(array &$definitions,
   unset($definitions['system_main_block']);
   // @todo Restore the page title block in https://www.drupal.org/node/2938129.
   unset($definitions['page_title_block']);
-}
+  // Add a boolean marker '_ui_patterns_compatible' to all remaining definitions
+  // Other modules can use the same hook to modify this value.
+  // This allows to whitelist or blacklist blocks.
+  $whitelisted_blocks = [
+    "id" => ["search_form_block", "system_menu_block"],
+    "provider" => ["views"],
+  ];
+  foreach ($definitions as $id => &$definition) {
+    if (isset($definitions[$id]['_ui_patterns_compatible'])) {
+      // When a block plugin already has 'ui_patterns_compatibilty'
+      // It probably means it has been marked by another code.
+      // Honor what the other code has done and do not override.
+      continue;
+    }
+    $compatibilityFlag = TRUE;
+    if (in_array($definition['provider'], $whitelisted_blocks["provider"]) ||
+      in_array($definition["id"], $whitelisted_blocks["id"])) {
+      // Those blacks are accepted.
+    }
+    elseif (isset($definition['class'])) {
+      try {
+        $class_name = $definition['class'];
+        $reflector = new \ReflectionClass($class_name);
+        if ($reflector->hasMethod("blockSubmit") && ($reflector->getMethod("blockSubmit")->getDeclaringClass()->getName() === $class_name)) {
+          // Blocks having a custom implementation are discarded,
+          // because some blocks may store in their configuration
+          // a different structure than the form structure.
+          // We can't support this properly yet.
+          $compatibilityFlag = FALSE;
+        }
+      }
+      catch (\ReflectionException $e) {
 
-/**
- * Implements hook_plugin_filter_TYPE_alter().
- */
-function ui_patterns_plugin_filter_block_alter(array &$definitions, array $extra, $consumer) {
-  // @todo Determine the 'inline_block' blocks should be allowed outside
-  //   of layout_builder https://www.drupal.org/node/2979142.
-  if ($consumer !== 'layout_builder' || !isset($extra['list']) || $extra['list'] !== 'inline_blocks') {
-    foreach ($definitions as $id => $definition) {
-      if ($definition['id'] === 'inline_block') {
-        unset($definitions[$id]);
       }
     }
+    // Filter out blocks with _block_ui_hidden ?
+    $definitions[$id]['_ui_patterns_compatible'] = $compatibilityFlag;
   }
 }